简体   繁体   English

C - 无法释放分配的 memory

[英]C - Unable to free allocated memory

I have a problem with an application I'm currently developing.我目前正在开发的应用程序有问题。 In this program I have to read huge amounts (billions) of data from text files and manage them consequently, but since it's a two students project, the reading part will be developed by my mate.在这个程序中,我必须从文本文件中读取大量(数十亿)数据并进行管理,但由于这是一个两个学生的项目,所以阅读部分将由我的伙伴开发。 For testing reason I wrote a small procedures that generates pseudo-random structures to replace what my mate will do.出于测试原因,我编写了一个小程序来生成伪随机结构来代替我的伙伴所做的事情。

The problem is the following: a big amount of the generated data (due to redundancy) can be discarded in order to free its memory.问题如下:可以丢弃大量生成的数据(由于冗余)以释放其 memory。 But even invoking the free() function the memory usage keeps growing.但即使调用 free() function memory 的使用量也在不断增长。 So I tried to develop a debug application that simply generates a chunk of data and immediately frees it.所以我尝试开发一个调试应用程序,它可以简单地生成一大块数据并立即释放它。 And repeats that for thousands of times.并重复数千次。 Well, I can't grasp the reason, but the memory allocated to the process grows to ~1.8 GB ram and then crashes.好吧,我不明白原因,但分配给进程的 memory 增长到 ~1.8 GB 内存然后崩溃。 Why?为什么? The strangest thing, that makes me thing there's a lot I'm not understanding well, is that when the process crashes the malloc does NOT return a NULL pointer, because the process always crashes when readCycles == 6008 and bypasses the NULL check. The strangest thing, that makes me thing there's a lot I'm not understanding well, is that when the process crashes the malloc does NOT return a NULL pointer, because the process always crashes when readCycles == 6008 and bypasses the NULL check.

I already read other related topics here on StackOverflow and I understood why free() doesn't reduce the memory allocated to my process.我已经在 StackOverflow 上阅读了其他相关主题,并且我理解了为什么 free() 不会减少分配给我的进程的 memory。 That's fine.没关系。 But why the memory usage keeps growing?但是为什么 memory 的使用量不断增长呢? Shouldn't the malloc allocate previously freed memory instead of constantly requesting new one? malloc 不应该分配先前释放的 memory 而不是不断请求新的吗?

This is the most relevant part of my code:这是我的代码中最相关的部分:

#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;

}

I forgot to mention that, but before posting here, instead of calling free(inputStream), I tried invoking freeMemory(inputStream).我忘记提了,但在这里发帖之前,我没有调用 free(inputStream),而是尝试调用 freeMemory(inputStream)。 Not sure if it's the correct way of doing it, though.不过,不确定这是否是正确的做法。

void freeMemory(MatePair* memblock){

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

}

Memory leaks. Memory 泄漏。 How many 'malloc()' you have called, how many 'free()' you must use to free all allocated memory on the heap.您调用了多少个“malloc()”,必须使用多少个“free()”来释放堆上所有已分配的 memory。

Thus,因此,

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

these 'malloc()' functions must be paired with free().这些“malloc()”函数必须与 free() 配对。

You're not freeing all members allocated within the read loop, hence you're losing memory eahc time.您没有释放在读取循环中分配的所有成员,因此您失去了 memory eahc 时间。 Remember, you have to free everything you allocate with a malloc, not just your array.请记住,您必须释放您使用 malloc 分配的所有内容,而不仅仅是您的阵列。

Ok, Just look at your edit, and your freeMemory is still wrong.好吧,看看你的编辑,你的 freeMemory 仍然是错误的。 Try this;尝试这个;

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);
  }

Your free(memblock) was in the loop, which it shouldn't have been, and I'd tend to use the same iteration sequence on freeing as mallocing.你的 free(memblock) 在循环中,它不应该是,我倾向于在释放时使用与 mallocing 相同的迭代序列。 You also need to error check after each malloc, and decide what to do with a NULL at that point.您还需要在每个 malloc 之后进行错误检查,并在此时决定如何处理 NULL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM