在C中检测到HEAP腐败

时间:2013-05-09 18:12:21

标签: c heap-memory corruption

我的程序遇到一些问题并收到此错误: HEAP CORRUPTION DETECTED:正常块(#9873672)之前的0x00968988。 CRT检测到应用程序在启动堆缓冲区之前写入内存。

我试图寻找修复程序,但我无法弄清楚我的程序出了什么问题,修复了什么以及在哪里:( 这是我正在使用的功能,这会导致我出现问题: 我正在做的基本上是查看特定关键字(函数getText的参数)的文件并打印其匹配值。 很抱歉,如果大多数变量都是法语,它是一个学校项目,我们的老师要求我们使用法语名称> _<

#include "getText.h"
#include "main.h"
#include <stdlib.h>

texteLangue* ressourcesTexteLangue = NULL;
int compteur = 0;


char* getText(char* clef)
{
    char* texte = NULL;
    texte = clef; //clef is the keyword passed in the function as argument
    texteLangue temp;
    temp.clef = clef;
    texteLangue* resultat = (texteLangue*) bsearch(&temp, ressourcesTexteLangue, compteur, sizeof(texteLangue), comparerClef); //returns the value associated with the key

    if (clef != NULL)
    {
            if (resultat != NULL)
            texte = resultat->valeur;
    }
    return texte; 
}

void lectureTexte(char* langue)
{
    char nomFichierRessources[64];
    sprintf(nomFichierRessources, "ressources_%s.txt", langue); //give the file name a specific ending depending on the language chosen
    FILE* FichierRessources = fopen(nomFichierRessources, "r");
    if (FichierRessources == NULL)
    {
        system("cls");
        perror("The following error occured ");
        system("PAUSE");
        exit(42);
    }

        //allocates memory for the language resources 
    int taille = 10;
    ressourcesTexteLangue = (texteLangue *) calloc(taille, sizeof(texteLangue));
    if (ressourcesTexteLangue == NULL)
        printf("Pas assez de place mémoire pour les ressources texte");


        //gives a value to TextResource.key and TextResource.value for each line of the file
    char* ligne;
    while ((ligne = lectureLigne(FichierRessources)))
    {
        if (strlen(ligne) > 0)
        {
            if (compteur == taille)
            {
                taille += 10;
                ressourcesTexteLangue = (texteLangue *) realloc(ressourcesTexteLangue, taille * sizeof(texteLangue));
            }
            ressourcesTexteLangue[compteur].clef = ligne;

            while (*ligne != '=')
            {
                ligne++;
            }

            *ligne = '\0';
            ligne++;
            ressourcesTexteLangue[compteur].valeur = ligne;
            compteur++;
        }
     }
         //sorts out the values of TextResource obtained
     qsort(ressourcesTexteLangue, compteur, sizeof(texteLangue), comparerClef);

     fclose(FichierRessources);
}

 //reads a line and returns it
 char* lectureLigne(FILE *fichier)
 {
    int longeur = 10, i = 0, c = 0;
    char* ligne = (char*) calloc(longeur, sizeof(char));

    if (fichier)
    {
        c = fgetc(fichier);
        while (c != EOF)
        {
            if (i == longeur)
            {
                longeur += 10;
                ligne = (char*) realloc(ligne, longeur * sizeof(char));
            }
            ligne[i++] = c;
            c = fgetc(fichier);
            if ((c == '\n') || (c == '\r'))
                break;
        }

        ligne[i] = '\0';

        while ((c == '\n') || (c == '\r'))
            c = fgetc(fichier);
        if (c != EOF)
            ungetc(c,fichier);

        if ((strlen(ligne) == 0) && (c == EOF))
        {
            free(ligne);
            ligne = NULL;
        }
    }
    return ligne;
}

//frees the TextRessources
void libererTexte()
{
    if (ressourcesTexteLangue != NULL)
    {
        while (compteur--)
        {
            free(ressourcesTexteLangue[compteur].clef);

        }
        free(ressourcesTexteLangue);
    }
}

//compares the keys
int comparerClef(const void* e1, const void* e2)
{
    return strcmp(((texteLangue*) e1)->clef, ((texteLangue*) e2)->clef);
}

RessourceTextelangue(TextResources)的结构如下所示:

typedef struct texteLangue {
    char* clef;
    char* valeur;
} texteLangue;

2 个答案:

答案 0 :(得分:1)

您的输入是否保证每行包含'='?

while (*ligne != '=') // if not, this will fly off the end of your buffer...
{
    ligne++;
}

*ligne = '\0'; // ...and write to unallocated heap memory

修改

鉴于@ Heath的评论,如果你的输入包含一个空白行(包括以一个空白行结尾),那么肯定会触发上述内容。

c = fgetc(fichier); // reads '\n'
while (c != EOF)
{
    ...

    ligne[i++] = c;

    ...

    ligne[i] = '\0';

ligne现在包含“\ n”并返回。以后用它:

if (strlen(ligne) > 0) // strlen("\n") is greater than 0
{
    ...

    while (*ligne != '=') // oops! loop until we find a '=' somewhere
                          // in the heap or crash trying.
    {
        ligne++;
    }

    *ligne = '\0'; // corrupt the heap here

答案 1 :(得分:1)

您的代码存在一些可能导致您看到的错误报告的潜在问题。

这是一个:

    if (i == longeur)

应该是:

    if ((i+1) == longeur)

否则,

    ligne[i] = '\0';

可以在

的条件下发生
        ligne[i++] = c;

导致i等于longeur

这是另一个:

        while (*ligne != '=')
        {
            ligne++;
        }

        *ligne = '\0';

上面的代码应该是:

        while (*ligne != '=' && *ligne != '\0')
        {
            ligne++;
        }

        *ligne = '\0';

否则,如果在字符串中找不到'=',则会损坏内存。

虽然其中任何一种都可能导致你报告的症状,但我看到其他一些奇怪的事情让我觉得到目前为止还有比我看到的更多错误。然而,解决这两个问题至少会减少你必须考虑的可能性。