(Désolé pour la fin du titre qui n'est pas complète, je voulais bien sûr parler de "pointeur").
Bonsoir
Pour les besoins d'un programme nécessitant les performances que le C a à offrir, je dois jouer avec les pointeurs.
Dans ce cas précis, j'ai une structure contenant des informations, souhaitant posséder plusieurs informations, il me faut donc un tableau de cette structure, et pour la modifier depuis des fonctions, il me faut un pointeur sur ce tableau de structure.
Voici un exemple qui résume la situation :
typedef struct Data {
int x;
char* y;
...
} Data;
void initDico(Data** array, size_t initSize) {
*array = (Data*)malloc(initSize * sizeof(Data));
}
void addItem(Data** array, Data item){
// Je dois donc réallouer la mémoire
*array = realloc(*dico, 20); // '20' c'est un exemple évidemment, afin de ne pas churcharger
// Ajout d'un élément
}
Data* arrayOfData;
init(&arrayOfData, 1); // J'initialise la taille du tableau à 1
addItem(&arrayOfData, /* un nouvel élément du type "Data" */);
Lorsque je teste, le programme s'arrête durant l'exécution, donc quelque chose c'est mal produit, et le problème survient à la 13ème ligne dans ce code, lorsque la fonction d'ajout d'élément est appelée.
Il y a peut-être d'autres choses à modifier dans ce code au niveau des allocations dynamiques, mais je ne vois pas en quoi ce que j'ai fais fait crasher le programme...
Pardon, `dico` est le nom réel dans mon code, j'ai fait une erreur de frappe. Il faut juste remplacer `dico` par `array` :
typedef struct Data {
int x;
char* y;
...
} Data;
void init(Data** array, size_t initSize) {
*array = (Data*)malloc(initSize * sizeof(Data));
}
void addItem(Data** array, Data item){
// Je dois donc réallouer la mémoire
*array = realloc(*array, 20); // '20' c'est un exemple évidemment, afin de ne pas churcharger
// Ajout d'un élément
}
Data* arrayOfData;
init(&arrayOfData, 1); // J'initialise la taille du tableau à 1
addItem(&arrayOfData, /* un nouvel élément du type "Data" */);
Il est fort peu probable que ce soit la ligne 13 qui fasse planter ton programme, l'erreur doit être ailleurs ! Dans une partie du code que tu nous ne montre pas !
Le bout de code que tu fournis ne fail pas chez moi. Peux-tu donner le message d'erreur que tu obtiens, ainsi que le scénario dans lequel tu l'obtiens?
typedef struct Variable Variable; // Défini autre part, mais le contenu n'est pas intéressant ici
typedef struct {
Variable* array;
size_t
size, // Taille allouée
used; // Espace utilisé
} VarDico;
void initDico(VarDico* dico, size_t initSize) {
dico->array = (Variable*)malloc(initSize * sizeof(Variable));
dico->used = 0;
dico->size = initSize;
}
void addVariable(VarDico* dico, Variable new) {
if (dico->used == dico->size) {
dico->size *= 2; // Je double la taille allouée à chaque fois
dico->array = (Variable*)realloc(dico->array, dico->size * sizeof(Variable));
if (dico->array == NULL) perror("Out of memory");
}
dico->array[dico->used++] = new; // J'ajoute le nouvel élément dans le tableau
}
// Usage :
VarDico dico;
initDico(&dico, 1);
Variable new = /* Nouvelle variable */; printf("\nAdding variable…\n");
addVariable(&dico, new);
printf("\nEnd of program\n");
Plus que ça serait futile, il me semble; désolé de ne pas l'avoir montré plus tôt mais je pense faire parti des programmeurs qui ont un peu peur de montrer leur code…
Donc là, il affiche "Adding variable..." mais crache dans la fonction addVariable.
Au début, j'initialise la taille à 1 élément, dico.used est donc différent de dico.size, une allocation de mémoire n'étant donc pas nécessaire, le programme passe donc à l'instruction suivante :
dico->array[dico->used++] = new;
Incrémentant donc la variable used, ce qui permettra de faire une nouvelle allocation de mémoire la prochaine fois et ainsi de suite.
Donc effectivement, ça ne provient probablement pas de "la ligne 13" après réflexion, ça ne pourrait venir que de l'instruction d'ajout de l'élément.
Merci pour le code, il est toujours important de montrer le code pour qu'on puisse t'aider Mais là encore, ton code fonctionne très bien chez moi avec une structure variable qui ne possède qu'un int en tant qu'attribut. Est ce que l'ajout de la première variable dans ton tableau fonctionne?
Écoutez, je suis vraiment désolé de vous avoir fait perde votre temps…
J'ai finalement trouvé "où" était l'erreur, mon code était en effet fonctionnel, mais pour une raison obscure, après avoir effacé les fichiers objets générés par GCC (ce que je ne fais pratiquement jamais parce que je n'y pense pas), le programma a correctement fonctionné (pourtant c'était le même qu'avant).
Si vous avez une explication à ça…
Je vous remercie pour votre patience tout de même.
C'est nice que ton problème soit résolu. Si effacer les fichiers a tout remis en ordre c'est que tu devais avoir une ancienne version d'un fichier dans ta chaine de compilation(par conséquent un fichier qui contenait du code erroné ou ancien)^^ Tu procèdes comment pour compiler ton projet (makefile, tout à la main...) ?
Si effacer les fichiers a tout remis en ordre c'est que tu devais avoir une ancienne version d'un fichier dans ta chaine de compilation(par conséquent un fichier qui contenait du code erroné ou ancien)
Oui, ça doit surement être ça
Melin Alexandre a écrit:
Tu procèdes comment pour compiler ton projet (makefile, tout à la main...) ?
Le Makefile est beaucoup moins galère quand on tire profit
des règles et dépendances implicites du Makefile
de la génération des dépendances explicites par le compilateur
Soit par exemple un programme avec un main dans prog.c et des sources foo.c, bar.c, baz.c ainsi que les .h, les uns dépendant des autres, etc.
Voila le Makefile
#
# Les options de compilation
#
CFLAGS = -std=c18
CFLAGS += -Wall -Wextra
CFLAGS += -MD # génération des dépendances
#
# mon projet
#
prog : prog.o foo.o bar.o baz.o # that's all !
-include $(wildcard *.d) # inclusion des dépendances
Explication :
quand on compile un programme toto.c avec l'option -MD de gcc (et llvm ?), ça génère en même temps un fichier toto.d contenant un petit makefile avec ses dépendances (les fichiers .h qu'il inclut, directement ou pas)
l'include du Makefile dit d'inclure ces makefiles, avant d'exécuter les cible voulues
la fabrication de prog.o se fait implicitement, puisqu'il traine un prog.c dans le répertoire, en utilisant la macro COMPILE.c, qui fait ce qu'il faut en utilisant les variables CFLAGS etc.
la fabrication de prog à partir de prog.o et d'autres se fait implicitement en lançant une macro LINK.c
les dépendances se mettent donc à jour toutes seules, automagiquement.
Piège à con (moi) : ne pas mettre l'include au début (parce que make lancera la première cible contenue dans le premier .d).
- Edité par michelbillaud 30 août 2019 à 20:10:17
Réallouer de la mémoire à un tableau depuis un ptr
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.