Et comme structure de données j'utilise la liste chainée:
typedef struct REF {
char* reference; // la donnée proprement dite
struct REF* next; // pointeur vers la reference suivante (ou 0 s'il n'y a plus de donnée)
}REF;
Le débogage gère l'exception dans la partie du fonction suivante :
void characters(void* user_data, const xmlChar *ch, int len) {
if (_inID && len) {
// On va enregistrer l'ID, mais en supprimant les espaces qui semblent s'être introduits 5
while(len>1 && *ch ==32) {
len--;
ch+=sizeof(xmlChar);
}
// On supprime également les espaces qui suivent la valeur.
while(len>1 && *(ch+len-1)==32)
len--;
_concepts[_currentCpt].ID = (char*)malloc(len+1);
strncpy(_concepts[_currentCpt].ID, ch, len);
*(_concepts[_currentCpt].ID+len) = 0;
_inID = 0;
}
else if ((_inIntent || _inUpperCovers || _inExtent) && len)
{
// lien vers les references du concept courant
REF** source;
REF* ref;
REF* newRef;
if (_inIntent)
source = &(_concepts[_currentCpt].intent);
else if (_inUpperCovers)
source = &(_concepts[_currentCpt].upperCovers);
else if (_inExtent)
source = &(_concepts[_currentCpt].extent);
ref = *source;
// on créé une nouvelle reference
newRef = (REF*)calloc(1, sizeof(REF));
// permet de relier la nouvelle reference a la structure (liste chainee)
if (ref) {
// La liste contient au moins une cellule.
// On va parcourir la liste a la recherche de la dernière cellule (celle qui à le pointeur next à NULL)
while(ref->next)
ref = (REF*)ref->next;
ref->next = newRef;
}
else
*source = newRef; // Première cellule de la liste chainée
// on recopie la donnée
newRef->reference = (char*)malloc(len+1);
strncpy(newRef->reference, ch, len);
// 0 terminal de la chaine de caractères
*(newRef->reference+len) = 0;
// Remise à 0 des flags de position
_inIntent _inUpperCovers _inExtent = 0;
}
}
Et exactement le flèche jaune pointe sur l'instruction suivante :
while(ref->next)
qui fait partie du code suivant de la fonction au dessus:
if (ref) {
// la liste contient au moins une cellule.
// on va parcourir la liste a la recherche de la dernière cellule (celle qui à le pointeur next à null)
while(ref->next)
ref = (ref*)ref->next;
ref->next = newref;
}
Donc, la structure de liste n'est pas la cause de cette exception.
concernant l'exception 0xfeeefeee:
Sous Windows, 0xfeeefeee indique une zone mémoire qui vient d'être libérée (par un free() ou équivalent).
Dans google, Je trouve cette information sur 0xfeeefeee:
Il est souvent utile de connaitre le code de memoire en mode debug.
Bien souvent les problemes de bases en C++ sont lie a la manipulation de la memoire (pointer NULL, non initialise, variable effacee mais reutilisee…).
Ceux a connaitre par coeur sont 0xcdcdcdcd qui veut dire non initalise et 0xfeeefeee qui veut dire deja efface.
nickydaquick
Messages postés416Date d'inscriptionvendredi 31 janvier 2003StatutMembreDernière intervention19 décembre 20133 5 oct. 2009 à 18:05
Salut,
lorsque tu declare un pointeur, il pointe sur un espace aleatoire en memoire (espace auquel tu n'y as peut-etre pas acces).
Solution: mets tes pointeurs a NULL (ou encore 0) a l'initialisation et verifie dans ton code avec une comparaison a 0 avant d'acceder a l'espace memoire.
Bonne continuation.
je suis heureux de faire partie d'une grande famille ...!
mezaya
Messages postés202Date d'inscriptiondimanche 18 mai 2003StatutMembreDernière intervention 6 mars 2010 8 oct. 2009 à 00:37
en debug pour chaque bloc que tu alloue, l'allocateur visual remplis ton buffer de 0xcdcdcdcd. quand tu le free, il le remplis de 0xdddddddd. Quand la page mémoire est libéré il remplis du 0xfeeefeee. Donc tu est en train de lire dans de la mémoire qui a été libéré. du déférence ton pointeur ref qui pointe sur une zone mémoire deleté et remplis de 0xfeeefeee. le champ next se trouve a 4 octet du début de ta structure. donc on final on obtient 0xfeeefeee + 0x4 = 0xfeeefef2.
Toujours bien faire attention à la durée de vie des objets.
tpoinsot
Messages postés345Date d'inscriptionmardi 1 juin 2004StatutMembreDernière intervention17 octobre 20144 8 oct. 2009 à 13:13
bonjour,
je ne pense pas que ce soit le déréférencement; comme nickydaquick l'a dit, après une allocation mémoire, il y a fortement intérêt à initialiser la zone allouée.
Par exemple avec memset, ou plus proprement en mettant à NULL chaque élement de la structure.
En particulier, newref->next n'est pas initialisé à NULL donc le next de la racine pointe n'importe où, et ça plante.
Donc, après le calloc de newref, il faut initialiser tous les éléments de la structure, et surtout le next.