Probleme de restitution de la mémoire

gergalp Messages postés 70 Date d'inscription vendredi 14 février 2003 Statut Membre Dernière intervention 20 mars 2007 - 6 juin 2005 à 15:07
gergalp Messages postés 70 Date d'inscription vendredi 14 février 2003 Statut Membre Dernière intervention 20 mars 2007 - 6 juin 2005 à 23:42
à l'éxécution d'un programme, j'ai un probleme au moment de restituer la mémoire. j'arrive pas à trouver d'ou ca vient.... c'est compilé avec VS .NET 2002 en mode debug


c'est pour utiliser la fonction sqlite3_exec de la lib SQLite 3


/*
* structures de données en utilisant une liste chainée
*/
typedef struct sql_result_item
{
char ** Rows;
struct sql_result_item * _next;
struct sql_result_item * _prev;
}sql_result_item;


typedef struct sql_result
{
int nColumns;
char ** Columns;
sql_result_item * _first;
sql_result_item * _last;
}sql_result;


/*
* duplication d'une chaine de caracteres
*/
char * strdup(const char * str)
{
int i;
char * ret;


if(str == NULL)
{
return NULL;
}


for(i = 0; str[i]; i++);


ret = malloc(sizeof(*str) * i);


ret[i] = '\0';
while(i)
{
i--;
ret[i] = str[i];
}


return ret;
}


/*
* fonction de callback appelée lors du traitement de la requete SQL
* Elle sert à mettre en forme les résultats
*/
int sql_query_callback(sql_result * result, int argc, char ** argv, char ** columnNames)
{
int i;
sql_result_item * item;


item = malloc(sizeof(*item));
item->_next = NULL;
item->Rows = malloc(sizeof(*item->Rows) * argc);


if(result->_first == NULL)
{
result->nColumns = argc;
result->Columns = malloc(sizeof(*result->Columns) * argc);
for(i = 0; i < argc; i++)
{
result->Columns[i] = strdup(columnNames[i]);
item->Rows[i] = strdup(argv[i]);
}
result->_first = item;
item->_prev = NULL;
}
else
{
for(i = 0; i < argc; i++)
{
item->Rows[i] = strdup(argv[i]);
}
item->_prev = result->_last;
result->_last->_next = item;
}
result->_last = item;


return 0;
}


/*
* et enfin, la fonction de restitution de la mémoire, celle qui pose probleme
*/
void sql_freeresult(sql_result * pDat)
{
int i;
sql_result_item * pItem;
sql_result_item * pBuff;


for(i = 0; i < pDat->nColumns; i++)
{
free(pDat->Columns[i]);
}
free(pDat->Columns);


pItem = pDat->_first;
while(pItem->_next)
{
for (i = 0; i < pDat->nColumns; i++)
{
free(pItem->Rows[i]);
}
free(pItem->Rows);
pBuff = pItem->_next;
free(pItem);
pItem = pBuff;
}


free(pDat);
}


VS .NET me renvoie:


Debug Error!


Program: H:\dev\sql_test\Debug\sql_test.exe


DAMAGE: after Notmal block (#351) at 0x00D86C58


apres, ca, il pointe la ligne 1154 du fichier dbgheap.c qui définit une partie de la fonction free() en mode debug:


if (!(_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF))
{
/* check no-mans-land gaps */
if (!CheckBytes(pHead->gap, _bNoMansLandFill, nNoMansLandSize))
_RPT3(_CRT_ERROR, "DAMAGE: before %hs block (#%d) at 0x%p.\n",
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead));


if (!CheckBytes(pbData(pHead) + pHead->nDataSize, _bNoMansLandFill, nNoMansLandSize))
_RPT3(_CRT_ERROR, "DAMAGE: after %hs block (#%d) at 0x%p.\n",
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead)); /* ligne 1154 */
}

pendant la génération, j'ai 2 avertissements:

sql_test warning LNK4075: ' /EDITANDCONTINUE' ignoré à cause de la spécification '/INCREMENTAL:NO'
sql_test warning LNK4098: conflit entre la bibliothèque par défaut 'LIBCMTD' et les autres bibliothèques ; utilisez /NODEFAULTLIB:library

2 réponses

vdust Messages postés 43 Date d'inscription jeudi 16 décembre 2004 Statut Membre Dernière intervention 14 mars 2007
6 juin 2005 à 22:49
Le code pointé après l'erreur est tout à fait logique.
D'ailleurs, si tu remarques bien, c'est précisément ce code qui t'a
envoyé le message d'erreur


_RPT3(_CRT_ERROR, "DAMAGE: after %hs block (#%d) at 0x%p.\n",

szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],

pHead->lRequest,
(BYTE *) pbData(pHead)); /* ligne 1154 */

(ceci constitue une seule et même instruction (en fait, une macro))




Le problème ne semble pas venir de ton code. Seule
solution restante (à moins d'un problème passé inaperçu ici (mais je ne
vois vraiment pas)), ça vient d'un autre endroit du programme qui
appelle ces fonctions.

Ce type d'erreur est typique de lorsque tu essaies de libérer une
mémoire déjà libérée. C'est donc qu'elle l'a été quelque part. Le tout
est de savoir où. Là, la solution la plus sûr (mais pas forcément la
plus rapide) est de faire un débogage pas à pas et de vérifier à chaque
étape le contenu des mémoires, pour savoir quand elles sont libérées
(et de repérer quel est le 'free' qui provoque l'erreur dans ta
fonction 'sql_freeresult', pour savoir ce qui pose problème). N'ayant
pas le reste du code, je ne peux t'en dire d'avantage.



++ et bon courage ^^


-- Virtual Dust --
0
gergalp Messages postés 70 Date d'inscription vendredi 14 février 2003 Statut Membre Dernière intervention 20 mars 2007
6 juin 2005 à 23:42
oki, je vais voir ca.

thx
0
Rejoignez-nous