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

C-无法释放已分配的内存,c,memory-management,crash,free,C,Memory Management,Crash,Free,我目前正在开发的应用程序有问题。在这个项目中,我必须从文本文件中读取大量(数十亿)数据并进行相应的管理,但由于这是一个两个学生的项目,阅读部分将由我的同伴开发。出于测试的原因,我编写了一个生成伪随机结构的小程序,以取代我的伴侣将要做的事情 问题如下:大量生成的数据(由于冗余)可以被丢弃以释放内存。但即使调用free()函数,内存使用量也在不断增长。所以我尝试开发一个调试应用程序,它只生成一块数据并立即释放它。并重复了数千次我无法理解原因,但分配给进程的内存增长到~1.8GB ram,然后崩溃。为

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

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

我已经阅读了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;

}

内存泄漏。调用了多少个“malloc()”,必须使用多少个“free()”来释放堆上所有分配的内存

因此,


这些“malloc()”函数必须与free()成对使用。

内存泄漏。调用了多少个“malloc()”,必须使用多少个“free()”来释放堆上所有分配的内存

因此,


这些“malloc()”函数必须与free()成对使用。

您没有释放在读取循环中分配的所有成员,因此您正在丢失内存。请记住,您必须释放使用malloc分配的所有内容,而不仅仅是数组

好的,只要看看你的编辑,你的自由内存仍然是错误的。试试这个

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);
  }
void freemory(配对*输入流)
{
对于(i=0;i

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

您没有释放在读取循环中分配的所有成员,因此您正在丢失内存。请记住,您必须释放使用malloc分配的所有内容,而不仅仅是数组

好的,只要看看你的编辑,你的自由内存仍然是错误的。试试这个

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);
  }
void freemory(配对*输入流)
{
对于(i=0;i

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

尝试为所有
malloc
调用添加检查,并使用valgrind运行程序。这也不是你的问题,但是
r=rand()/(rand_MAX+1)
总是
0
,除非你在分割之前向
double
添加一个强制转换。这里有几个内存泄漏,为inputstream[i]分配的内存在哪里。leftDNA等被释放。是的,我已经注意到了(double)的事情,忘了修改它,因为我更担心内存泄漏的问题:)我建议将DNA序列重新编码为字符数组(例如,char-leftDNA[SEQLEN])。这样,您就可以一次性分配struct数组,而不是分很多步骤。要完全跳过动态内存分配,请在readStream()调用之前在堆栈上声明struct数组,并将其传递给readStream()。我假设您的系统不是嵌入式系统,可以处理约300 kb的堆栈。问题是readStream()只是一个调试存根,在最终的应用程序中,在读取(并处理)第一个文本文件的第一行之前,我不会知道SEQLEN中的值,据我所知,这是唯一的方法,不是吗?(我可能错了,我上一个C语言程序已经好几年了,我从来都不是这方面的专家)尝试为所有
malloc
调用添加检查,并使用valgrind运行该程序。这也不是你的问题,但是
r=rand()/(rand_MAX+1)
总是
0
,除非你在分割之前向
double
添加一个强制转换。这里有几个内存泄漏,为inputstream[i]分配的内存在哪里。leftDNA等被释放。是的,我已经注意到了(double)的事情,忘了修改它,因为我更担心内存泄漏的问题:)我建议将DNA序列重新编码为字符数组(例如,char-leftDNA[SEQLEN])。这样,您就可以一次性分配struct数组,而不是分很多步骤。要完全跳过动态内存分配,请在readStream()调用之前在堆栈上声明struct数组,并将其传递给readStream()。我假设您的系统不是嵌入式系统,可以处理约300 kb的堆栈。问题是readStream()只是一个调试存根,在最终的应用程序中,在读取(并处理)第一个文本文件的第一行之前,我不会知道SEQLEN中的值,据我所知,这是唯一的方法,不是吗?(我可能错了,自从我上一个C语言课程开始已经好几年了
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);
  }