C - 无法释放已分配的内存

时间:2011-07-19 10:33:40

标签: c memory-management crash free

我正在开发的应用程序出现问题。在这个程序中,我必须从文本文件中读取大量(数十亿)数据并对其进行管理,但由于这是一个两个学生的项目,阅读部分将由我的伙伴开发。出于测试原因,我写了一个小程序,生成伪随机结构来代替我的伙伴会做的事情。

问题如下:为了释放内存,可以丢弃大量生成的数据(由于冗余)。但即使调用free()函数,内存使用量也在不断增长。所以我尝试开发一个调试应用程序,它只生成一大块数据并立即释放它。并重复了数千次。 好吧,我无法理解原因,但分配给该进程的内存增长到~1.8 GB ram然后崩溃。为什么?最奇怪的是,这让我有很多我不太了解的事情,就是当进程崩溃时,malloc不返回NULL指针,因为当readCycles == 6008并且绕过NULL检查时进程总是崩溃。 / p>

我已经在StackOverflow上阅读了其他相关主题,我理解为什么free()不会减少分配给我的进程的内存。没关系。但为什么内存使用量不断增长? malloc不应该分配以前释放的内存而不是不断地请求新的内存吗?

这是我的代码中最相关的部分:

#define NREAD 1000
#define READCYCLES 10000
#define N_ALPHA_ILLUMINA 7
#define N_ALPHA_SOLID 5
#define SEQLEN 76

typedef struct{
    char* leftDNA;
    char* leftQuality;
    unsigned long int leftRow;
    char* rightDNA;
    char* rightQuality;
    unsigned long int rightRow;
} MatePair;


unsigned long int readCycles = 0;


MatePair* readStream(MatePair* inputStream, short* eof, unsigned long int* inputSize){

    double r;
    unsigned long int i, j;
    unsigned long int leftRow;
    int alphabet[] = {'A', 'C', 'G', 'T', 'N'};
    inputStream = (MatePair*) malloc (sizeof(MatePair) * (NREAD + 1));
    printf("%d\n", readCycles);
    if (inputStream == NULL){
        (*eof) = 1;
        return;
    }

    for (i = 0; i < NREAD; i++){
        leftRow = readCycles * NREAD + i;
        inputStream[i].leftDNA = (char*) malloc (SEQLEN);
        inputStream[i].rightDNA = (char*) malloc (SEQLEN);
        inputStream[i].leftQuality = (char*) malloc (SEQLEN);
        inputStream[i].rightQuality = (char*) malloc (SEQLEN);
        for (j = 0; j < SEQLEN; j++){
            r = rand() / (RAND_MAX + 1);
            inputStream[i].leftDNA[j] = alphabet[(int)(r * 5)];
            inputStream[i].rightDNA[j] = alphabet[(int)(r * 5)];
            inputStream[i].leftQuality[j] = (char) 64 + (int)(r * 60);
            inputStream[i].rightQuality[j] = (char) 64 + (int)(r * 60);
        }
        inputStream[i].leftDNA[SEQLEN - 1] = '\0';
        inputStream[i].rightDNA[SEQLEN - 1] = '\0';
        inputStream[i].leftQuality[SEQLEN - 1] = '\0';
        inputStream[i].rightQuality[SEQLEN - 1] = '\0';
        inputStream[i].leftRow = leftRow;
        inputStream[i].rightRow = leftRow;
    }

    inputStream[i].leftRow = -1;

    readCycles++;
    (*inputSize) = NREAD;
    (*eof) = readCycles > READCYCLES;

    return inputStream;

}


int main(int argc, char* argv[]){

    short eof = 0;
    unsigned long int inputSize = 0;
    MatePair* inputStream = NULL;

    while (!eof){
        inputStream = readStream(inputStream, &eof, &inputSize);
        free(inputStream);
        inputStream = NULL;
    }

    return 0;

}

我忘了提到这一点,但在发布之前,我没有调用free(inputStream),而是尝试调用freeMemory(inputStream)。不过,不确定这是否是正确的做法。

void freeMemory(MatePair* memblock){

    for ( ; memblock->leftRow != 1; memblock++){
        free(memblock -> leftDNA);
        free(memblock -> leftQuality);
        free(memblock -> rightDNA);
        free(memblock -> rightQuality);
    }

}

2 个答案:

答案 0 :(得分:3)

内存泄漏。多少&#39; malloc()&#39;你打过电话,有多少人免费()&#39;你必须用来释放堆上所有已分配的内存。

因此,

inputStream[i].leftDNA = (char*) malloc (SEQLEN);
inputStream[i].rightDNA = (char*) malloc (SEQLEN);
inputStream[i].leftQuality = (char*) malloc (SEQLEN);
inputStream[i].rightQuality = (char*) malloc (SEQLEN);

这些&#39; malloc()&#39;函数必须与free()配对。

答案 1 :(得分:2)

你没有释放在读取循环中分配的所有成员,因此你正在失去内存eahc时间。请记住,您必须释放使用malloc分配的所有内容,而不仅仅是阵列。

好的,看看你的编辑,你的freeMemory仍然是错误的。试试这个;

void freeMemory(MatePair* inputStream)
{
    for (i = 0; i < NREAD; i++){
        free(inputStream[i].leftDNA);
        free(inputStream[i].leftQuality);
        free(inputStream[i].rightDNA);
        free(inputStream[i].rightQuality);
    }
    free (inputStream);
  }

你的自由(memblock)在循环中,它不应该是,并且我倾向于使用与mallocing相同的迭代序列。您还需要在每个malloc之后进行错误检查,并在此时决定如何处理NULL。