Liste de tableaux en C ne fonctionne pas
Je suis en train d'écrire un programme pour mettre en œuvre une liste de tableaux (ou un tableau dynamique) en C. Hmm... je pense que j'ai 70 - 80% de faire avec elle, cependant, j'ai trouvé un sérieux problème avec mon code lors de l'essai sur quelques machines.
Brièvement, j'ai inséré un groupe de chaînes de caractères( char* ) dans ma liste de tableaux, et essayé de le faire et de les afficher après les couples d'opérations. Cependant, c'est ce que j'ai:
CHECK: 1
CHECK: 2
CHECK: ܗ¿èۗ¿
CHECK: EàEàHAÿE؉Ⱥ
CHECK: 5
CHECK: 6
Malheureusement, je ne peux toujours pas comprendre où est le problème dans mes codes, même si j'ai passé en revue mes codes à deux reprises.
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;
}
OriginalL'auteur Slash_D | 2010-09-17
Vous devez vous connecter pour publier un commentaire.
Comme d'autres l'ont noté, le problème est dans la
arraylist_add()
fonction, qui doit allouer dynamiquement de la mémoire. Ce problème est en réalité parfaitement adapté pourrealloc()
, qui permettra d'élargir le tableau alloué dynamiquement (ce qui signifie que vous n'avez pas à faire de la copie de la boucle):Ce sera même travail pour la première affectation, depuis
realloc()
fonctionne commemalloc()
si vous passer unNULL
.PS:
Pour faire de la mise en œuvre plus efficace, vous ne devriez pas vous développez le tableau par une entrée à chaque fois - au lieu de cela, garder une trace du nombre de blocs alloués séparément à partir du nombre d'entrées.
OriginalL'auteur caf
Dans le
arraylist_add
la méthode de stocker l'adresse d'une variable localenew_data
dans la liste. Cette variable sera détruit dès que la commande vient de sortir de la fonction. Donc vous avez des pointeurs invalides qui, lorsqu'il derefrenced invoquer un comportement indéfini. Pour résoudre ce problème, vous devez allouer de la mémoire pour la chaîne de tas à l'aide demalloc
c'est à dire que vous devez faire quelque chose commevalue_type* new_data = (value_type*)malloc( (size + 1) * sizeof(value_type));
. Rappelez-vous aussi que vous avez à libérer cette mémoire vous-même à l'aide defree
.OriginalL'auteur Naveen
Au premier coup d'œil: dans arraylist_add vous déclarez new_data comme une variable locale. Lorsque vous transmettez à arraylist_set_data_collection, il passe le pointeur de ces données. Cependant, une fois que arraylist_add retourne à la page principale, new_data est hors de portée, et n'est donc plus valide.
Pensez à faire une copie en profondeur et de la manipulation de la mémoire manuellement avec malloc et free.
OriginalL'auteur Paul
La racine de votre problème est ici:
new_data
est déclaré sur la pile. Il n'est plus sûr à utiliser que la mémoire après les retours d'appel. Vous avez besoin d'allouer de l'espace pour les données avecmalloc
, par exempleOriginalL'auteur Grumdrig