2016-04-09 2 views
-1

У меня есть массив указателей на структуры, и я хочу удалить элемент и переместить все остальное, чтобы заполнить пробел. Я написал функцию, которая, похоже, работает, однако valgrind жалуется на «недопустимое чтение/запись размера 8», поэтому теперь мне интересно, было ли то, что я сделал, было неверным.Удаление элемента из массива указателей на структуры

Вот код:

for (int i = (numOfApartments-1); i >= 0; i--) { 
    if (apartmentIsIdentical(apartment, apartmentArray[i]->apartment)) { 
     apartmentDestroy(apartmentArray[i]->apartment); 
     free(apartmentArray[i]); 
     shiftApartments(apartmentArray, i, numOfApartments); 
     numOfApartments--; 
     return 1; 
    } 
} 

static void shiftApartments(ApartmentInfo* array, int startIndex, int endIndex) { 
    for (int i = startIndex; i < endIndex; i++) { 
     swapApartments(&array[i], &array[i + 1]); 
    } 
} 

static void swapApartments(ApartmentInfo* apartment1, ApartmentInfo* apartment2) { 
    ApartmentInfo temp = *apartment1; 
    *apartment1 = *apartment2; 
    *apartment2 = temp; 
} 

Мой вопрос заключается в основном ли ([я] apartmentArray) является правильным свободным. Как я вижу это, он должен оставить пустой слот, который я просто переместил в конец массива и поместил там что-то еще позже. Однако ошибка «неправильного чтения/записи размера 8» заставило меня задаться вопросом, освобождает ли квартирный массив [i] сделать доступный слот недоступным ..? Почему я говорю, что я не могу писать?

Спасибо!

+0

Предоставить [mcve]. Код, похоже, не использует am массив указателей, а массив 'ApartmentInfo'. – Olaf

ответ

0

, так как вы освободили apartmentArray [я], вы не можете поменять местами значения, просто присвоить указатель в shiftApartments

пытаются заменить

swapApartments(&array[i], &array[i + 1]); 

с

array[i] = array[i+1]; 
+0

Так как я могу удалить элемент, если не могу поменять значения? Я не совсем понял, что означает «просто назначить указатель в shiftApartments». Будет ли это работать, если я сначала перенесите элементы, а затем бесплатно? смогу ли я снова использовать этот слот? – Anna

+0

вы не должны пытаться изменить значения, поменяйте указатели. – Turo

0

memmove() является вашим другом Вот. Memmove обрабатывает случаи перекрывающихся ходов и может избегать явного цикла. Единственная трудность - получить правильные размеры!

(я использую массив указателей на характер, но это, по существу, не отличается от указателей на структуру. Кроме того, что вы не должны пытаться освободить() их ;-)

#include <stdio.h> 
#include <string.h> 

int main(void) 
{ 
char *array[] = { "one", "two", "three", "four" 
       , "five", "six", "seven", "eight" }; 

     /* using an array of pointers to string literals 
     ** , so free() should not be used here ... 
     */ 
#define SHOULDFREE(s) fprintf(stderr,"Should free %s\n", s) 

unsigned size = 8; 
unsigned idx,top; 

for (top=idx=size; idx-- > 0; ) { 
       /* only delete words that start with 't' */ 
     if (*array[idx] != 't') continue; 
     SHOULDFREE(array[idx]); 
     top--; 
     if (idx >=top) continue; 
     fprintf(stderr,"about to move %u (%s) (%u elements) one place down\n" 
         , idx+1, array[idx+1], top-idx); 
     memmove(&array[idx], &array[idx+1], (top-idx) * sizeof array[0]); 
     } 
for (idx=0; idx < top; idx++) { 
     printf("[%u]: %s\n", idx, array[idx]); 
     } 
return 0; 
} 

И, конечно,

memmove(&array[idx], &array[idx+1], (top-idx) * sizeof array[0]);

может быть заменен:

memmove(array+idx, array+idx+1, (top-idx) * sizeof array[0]);

Смежные вопросы