Arraylist in C funktioniert nicht
Ich bin derzeit am schreiben eines Programms zur Einführung einer arraylist (oder dynamisches array) in C. Hmm... ich glaube, ich habe 70 - 80% fertig, allerdings fand ich ein ernstes problem mit meinem code, wenn Test auf ein paar Maschinen.
Kurz, ich trug eine Gruppe von strings( char* ) in meine arraylist, und versucht, Sie zu bekommen und zeigen Sie Sie nach Paare von Operationen. Dies ist jedoch, was ich habe:
CHECK: 1
CHECK: 2
CHECK: ܗ¿èۗ¿
CHECK: EàEàHAÿE؉Ⱥ
CHECK: 5
CHECK: 6
Leider kann ich immer noch nicht herausfinden, wo das problem in meinem Code, selbst wenn ich überprüft haben meine codes doppelt.
arraylist.h
#ifndef _ARRAYLIST_H
#define _ARRAYLIST_H
#include <stdio.h>
typedef char* value_type;
struct arraylist {
int size;
value_type* data;
};
extern void arraylist_initial(struct arraylist *list);
extern int arraylist_get_size(const struct arraylist list);
extern value_type* arraylist_get_data_collection(const struct arraylist list);
extern void arraylist_set_data_collection(struct arraylist *list, value_type* data);
extern void arraylist_add(struct arraylist *list, value_type value);
extern value_type arraylist_get(const struct arraylist list, int index);
extern int arraylist_indexof(const struct arraylist list, value_type value);
#endif
arraylist.c
#include "arraylist.h"
void arraylist_initial(struct arraylist *list) {
list->size = 0;
list->data = NULL;
}
int arraylist_get_size(const struct arraylist list) {
return list.size;
}
value_type* arraylist_get_data_collection(const struct arraylist list) {
return list.data;
}
void arraylist_set_data_collection(struct arraylist *list, value_type* data) {
list->data = data;
}
void arraylist_add(struct arraylist *list, value_type value) {
int size = arraylist_get_size(*list);
value_type new_data[size + 1];
int index = 0;
for(; index != size; ++index) {
new_data[index] = arraylist_get(*list, index);
}
new_data[index] = value;
arraylist_set_data_collection(list, new_data);
++list->size;
}
value_type arraylist_get(const struct arraylist list, int index) {
if(index < arraylist_get_size(list)) {
return list.data[index];
}
else {
return NULL;
}
}
int arraylist_indexof(const struct arraylist list, value_type value) {
int index = 0;
for(; index != arraylist_get_size(list); ++index) {
if(strcmp(list.data[index], value) == 0) {
return index;
}
}
return -1;
}
int main(void){
struct arraylist list;
arraylist_initial(&list);
arraylist_add(&list, "1");
arraylist_add(&list, "2");
arraylist_add(&list, "3");
arraylist_add(&list, "4");
arraylist_add(&list, "5");
arraylist_add(&list, "6");
int index = 0;
for(; index != 6; ++index) {
printf("CHECK: %s\n", arraylist_get(list, index));
}
return 0;
}
InformationsquelleAutor Slash_D | 2010-09-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie andere bemerkt haben, ist das problem in der
arraylist_add()
Funktion, die dynamisch Speicher reservieren. Dieses problem ist eigentlich perfekt geeignet fürrealloc()
, das wird erweitern Sie den dynamisch reservierten Arrays (so dass Sie nicht haben, um die Kopier-Schleife):Dadurch wird auch die Arbeit für die erste Zuteilung, da
realloc()
funktioniert wiemalloc()
wenn Sie es übergebenNULL
.PS:
Um die Umsetzung effizienter, sollten Sie nicht erweitern Sie das array durch einen Eintrag jedes mal - stattdessen verfolgen die Anzahl der zugewiesenen Blöcke getrennt von der Anzahl der Einträge.
InformationsquelleAutor caf
In der
arraylist_add
Methode, die Sie speichern die Adresse einer lokalen variablenew_data
in der Liste. Diese variable wird zerstört, sobald die Kontrolle kommt aus der Funktion heraus. Somit haben Sie die ungültige Zeiger, die, wenn derefrenced aufrufen zu undefiniertem Verhalten. Um dieses problem zu beheben, müssen Sie Speicher für den string vom heap, dermalloc
also müssen Sie etwas tun, wievalue_type* new_data = (value_type*)malloc( (size + 1) * sizeof(value_type));
. Denken Sie auch daran, dass Sie zum freigeben dieses Speichers selbst mitfree
.InformationsquelleAutor Naveen
Auf den ersten Blick: in arraylist_add erklären Sie new_data als eine lokale variable. Wenn Sie übergeben, arraylist_set_data_collection, es geht der Zeiger auf diese Daten. Allerdings, wenn arraylist_add zurück zu main, new_data out of scope, und ist daher nicht mehr gültig.
Berücksichtigen Sie dabei ein tiefes kopieren und Handhabung der Speicher manuell mit malloc und free.
InformationsquelleAutor Paul
Die Wurzel des Problems ist hier:
new_data
ist auf dem Stapel deklariert. Es ist nicht mehr sicher zu verwenden, dass der Speicher nach dem Aufruf zurück. Sie benötigen, um Speicherplatz für die Daten mitmalloc
z.B.InformationsquelleAutor Grumdrig