C-Array in Größe dynamisch verändern

25/02/2009 - 22:58 von Tom Seidel | Report spam
Schönen Abend!

Ich habe hier ein kleines Problem bei dem ich mir über seine Richtigkeit
nicht ganz sicher bin:

Gegeben ist eine Funktion, deren Prototyp so aussieht:

int func(int *list, size_t size)

Nun soll die Funktion folgendes machen:
- gebe das erst Feldelement zurück, also list[0]
- verkürze das Array list derart das list[0] entfernt wird und somit nur
noch size - 1 Elemente darin enthalten sind

Folgender Code soll das ganze erreichen:

#include <stdio.h>
#include <stdlib.h>


int func(int *list, size_t size) {
int ret = list[0];
list = realloc(list, (size - 1) * sizeof(int));
int i;

for(i = 1; i < size; i++)
list[i-1] = list[i];

return ret;
}



int main(int argc, char *argv[]) {
int *list = malloc((argc-1) * sizeof(int));
int ret;
int i;

for(i = 1; i <= argc-1; i++) {
printf("%d", atoi(argv[i]));
list[i-1] = atoi(argv[i]);
}

func(list, argc-1);

printf("Neuer Listeninhalt: ");
for(i = 0; i < argc-2; i++) { /* I */
printf("Index %d: Wert %d", i, list[i]);
}
free(list);

return 0;
}

Soweit macht dieser Ausschnitt das was er soll, aber mich würde
interessieren, was erfahrene Anwender darüber denken?! Kann man das besser
machen? Was mich ein bisschen wundert, ist z.B., dass wenn ich bei I die
Abbruchbedingung auf argc-1 àndere, das letzte Element nachwievor
ausgegeben wird. Eigentlich hàtte ich da einen Speicherzugriffsfehler
erwartet, weil ich dachte, realloc würde den nun überschüssigen Speicher
freigeben.

Danke!
 

Lesen sie die antworten

#1 Alexander Bartolich
25/02/2009 - 23:15 | Warnen spam
Tom Seidel schrieb:
[...]
int func(int *list, size_t size) {
int ret = list[0];



Du gehst davon aus, dass size > 0 ist, überprüfst das aber nicht.

list = realloc(list, (size - 1) * sizeof(int));



Bei Speichermangel liefert realloc 0 zurück ohne den Speicherblock
zu veràndern.

int i;

for(i = 1; i < size; i++)
list[i-1] = list[i];



Das ist undefined behaviour.

Nach dem realloc liegt &list[size -1] außerhalb des Speicherblocks.
Da viele Implementierungen von realloc aber bei einer Verkleinerung
gar nichts tun (also auch keinen Speicher freigeben), kann das oft
gut gehen.

return ret;
}

Soweit macht dieser Ausschnitt das was er soll, aber mich würde
interessieren, was erfahrene Anwender darüber denken?!



Ganz unabhàngig von den Fehlern ist das ein kranker Algorithmus.
Wozu soll das gut sein?

seq 0 1 99 | xargs -I. echo 'Romani Ite Domum!'

Ähnliche fragen