2

我是 c 的新手。我有一些代码试图在 Cuda 中测试,但在提取数据时遇到了一些麻烦。我的数据位于一个文件(19GB)中,我基本上计划读取一定数量的行,将它们保存到一个列表中,发送他们对整个文件进行处理并再次执行此操作。

我刚开始学习如何做到这一点并且遇到了我不确定的 C 问题,当我运行程序时,我的内存不断增加(当我在我的 mac 上访问活动监视器时),但它是似乎与 c 程序无关,它只是显示非活动内存不断增长。即使在程序停止后,内存仍然处于非活动状态(恢复它的唯一方法是重新启动)。据我所知,它不会影响程序,但看起来很奇怪,我很想知道为什么以及是否/我能做些什么?

我对 malloc 和 free 有一点了解(对不起,我更了解 Java/Python 并且从来不必这样做)但我不确定我是否应该在这段代码中这样做,因为我认为line变量不断被覆盖。

这是代码:

int main() {
    printf("Starting..");
    char line[1024];
    FILE *fp = fopen("output.txt","r");

    if( fp == NULL ) {
        return 1;
    }
    int count = 0;
    while( fgets(line,1024,fp) ) {
        //printf("%s\n",line);
        count++;
    }
    printf(" num of lines is %i \n", count);

    return 0;
}

我很感激关于这里发生了什么的任何提示/建议,以及是否有更好的方法来做到这一点?

更新:对不起,我没有提到,我注意到的行为是在程序运行时。当它运行时,不活动的内存只会不断增长。我有大约 4 个免费演出,30 秒后它全部满了,重新启动是释放它的唯一方法(即使 c 程序被杀死,内存也没有被释放)。

4

3 回答 3

2

您的代码不分配任何内存(FILE结构除外),因此您没有任何取决于文件大小的泄漏。

但是,您确实fclose(fp);会泄漏一些内存,因为您在访问完文件后忘记了。

作为建议,如果您使用的是 linux,请使用valgrind --leak-check=full ./yourapp- 假设您的程序是使用调试符号(-ggcc 中的开关)编译的,您将获得详细的泄漏报告,准确显示您的程序是否/在何处泄漏内存。

于 2012-05-31T00:53:12.810 回答
2

这是完全正常的。释放内存需要付出努力。这种努力完全浪费了,因为一旦需要内存,系统只需将其从空闲池中删除即可。直接将内存从一种用途转移到另一种用途会更有效。所以这个系统是聪明的而不是愚蠢的。

这不像今天使用一半的内存,明天可以使用两倍的内存。所以释放内存没有任何好处。

当您从文件中读取行时,操作系统会从文件中读取整个块。如果可能,它会尝试将这些块保存在内存中,因为这样可以避免将来必须从磁盘读取。如果它没有更好的用途来存放内存,它会将这些文件块保存在内存中。这既节省了必须释放内存以再次使用内存的工作,又加快了以后对同一文件块的访问。

释放此内存没有任何好处。只是需要操作系统方面的努力才能使其免费,操作系统方面的努力才能使其将来再次使用,并且操作系统会失去避免磁盘读取的机会。因此,释放内存将是完全愚蠢的。

于 2012-05-31T01:03:11.553 回答
1

这是因为你使用

    fgets(buffer, int size, file);

which will only stop reading if you hit EOF. Theres 2 ways of fixing it, either use

    while(fgets(buffer, size, file) != EOF){};

or

    while(fread(buffer, sizeof(char), nmem, file) < 1024){};

I recommend using the latter, for some reason I tend to run into issues using fgets, and you have more control of what your doing with fread.

于 2012-05-31T01:21:39.693 回答