2016-04-09 16 views
-1

Ich habe ein Array von Zeigern auf Strukturen, und was ich tun möchte, ist ein Element zu löschen und den Rest verschieben, um die Lücke zu füllen. Ich habe eine Funktion geschrieben, die zu funktionieren scheint, aber valgrind beschwert sich über 'ungültiges Lesen/Schreiben von Größe 8', also frage ich mich, ob das, was ich getan habe, falsch war.Löschen eines Elements aus einem Array von Zeigern auf Strukturen

Hier ist der Code:

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; 
} 

Meine Frage ist vor allem, ob der freie (apartmentArray [i]) korrekt ist. So wie ich es sehe, sollte es einen leeren Slot lassen, den ich einfach an das Ende des Arrays ziehe und später noch etwas anderes platziere. Aber der Fehler 'ungültiges Lesen/Schreiben von Größe 8' ließ mich darüber nachdenken, ob die Freigabe von apartmentArray [i] den Slot tatsächlich unzugänglich macht ..? Warum heißt es, ich kann nicht schreiben?

Danke!

+0

Stellen Sie eine [mcve] bereit. Der Code scheint nicht ein Array von Pointer zu verwenden, sondern ein Array von 'ApartmentInfo'. – Olaf

Antwort

0

da Sie befreit apartmentArray [i], man kann die Werte tauschen, weisen nur den Zeiger in shiftApartments

try

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

mit

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

Also, wie lösche ich ein Element, wenn ich die Werte nicht tauschen kann? Ich habe nicht ganz verstanden, was "den Zeiger in shiftApartments einfach zuweisen" bedeutet. Würde es funktionieren, wenn ich zuerst die Elemente verschiebe und dann frei benutze? wäre ich in der Lage, diesen Slot wieder zu benutzen? – Anna

+0

sollten Sie nicht versuchen, die Werte zu tauschen, tauschen Sie die Zeiger aus. – Turo

0

memmove() ist dein Freund zu ersetzen Hier. Memmove handhabt die Fälle überlappender Bewegungen und kann eine explizite Schleife vermeiden. Die einzige Schwierigkeit besteht darin, die richtigen Größen zu erhalten!

(ich verwende ein Array von Zeigern auf Zeichen, aber das ist im Wesentlichen nicht anders als Zeiger auf struct. Abgesehen davon, dass Sie sollten nicht zu befreien versuchen(), um sie ;-)

#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; 
} 

Und natürlich

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

: die

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

könnte ersetzt werden durch

Verwandte Themen