这是我在从事的个人项目中遇到的问题的简化重现。
我正在尝试创建一个指向堆分配结构的指针堆数组。 那里的问题似乎是某个地方内存泄漏,我不太确定为什么会这样。
我使用任务管理器来跟踪我的程序使用的内存量。
这是用 C 语言编写的用于结构分配的代码,我使用代码块作为我的 IDE,如果这会影响任何内容,它会使用 GNU GCC 编译器。
#include <stdio.h>
#include <stdlib.h>
//My Struct as an example
typedef struct dog {
int Age;
int Weight;
} Dog;
typedef Dog* DGPtr;
// A function to Create a heap allocated instance of this struct
DGPtr CreateDog(int age, int weight){
DGPtr Ptr = (DGPtr) malloc(sizeof(Dog));
Ptr->Age = age;
Ptr->Weight = weight;
return Ptr;
}
int main(){
// I take inputs every now and then to be able to check in task manager where my ram is at during the process
char inp[10];
int size = 100000000;
DGPtr myPoint = CreateDog(5,5);
//Step 1 Malloc but no write
scanf("%s", inp);
DGPtr* ptrArr = malloc(sizeof(DGPtr) * size);
//Step 2 Write to malloc
scanf("%s", inp);
for (int i = 0; i < size; i++){
ptrArr[i] = (DGPtr) malloc(sizeof(Dog) * 1);
ptrArr[i]->Age = 7;
ptrArr[i]->Weight = 7;
}
//Step 3 Free All pointer in array
scanf("%s", inp);
for (int i = 0; i < size; i++){
free(ptrArr[i]);
}
//Step 4 Free Array
scanf("%s", inp);
free(ptrArr);
scanf("%s", inp);
return 0;
}
这是原始分配的代码:
int main(){
char inp[10];
int size = 100000000;
//Step 1 Malloc but no write
scanf("%s", inp);
int** ptrArr = malloc(sizeof(int *) * size);
//Step 2 Write to malloc
scanf("%s", inp);
for (int i = 0; i < size; i++){
ptrArr[i] = malloc(sizeof(int));
}
//Step 3 Free All pointer in array
scanf("%s", inp);
for (int i = 0; i < size; i++){
free(ptrArr[i]);
}
//Step 4 Free Array
scanf("%s", inp);
free(ptrArr);
scanf("%s", inp);
return 0;
}
我对原始数据类型进行了相同的实验,换句话说,我对整数进行了尝试。 重新创建一个 int 指针数组,然后将整数数组分配给这些指针。 我也遇到了一个问题,即内存泄漏比使用基本结构时要少一点。
是的,内存泄漏与我分配的数组的大小成比例。它看起来确实或多或少是线性扩展的,因为当我运行测试然后将数组大小扩大 10 倍时,内存泄漏也扩大了 10 倍,虽然不完全是,但非常接近,就像 9.something 一样。
以下是我运行实验时任务管理器的一些图像:
在结构指针数组开始分配之前: malloc 后内存分配看起来仍然相同,但未写入内存块 在我们刚刚写入的第 3 步中,我们得到了以下内容: 正如你所看到的,我们正在使用一些内存 在第 4 步,我们遍历了指针数组并释放了该数组中的所有指针,剩下的是: 最后释放指针数组后我们剩下这个
问题是,如您所见,我们仍在使用 11.2 MB 的 RAM,而在执行整个操作之前,我们只使用了 0.3 MB 的 RAM。
有人可以解释一下为什么在这个过程结束时我们仍然比以前使用更多的内存吗?以及该内存可能在哪里以及如何恢复到之前的内存使用水平。
第一个程序中唯一的漏洞是
DGPtr myPoint = CreateDog(5,5);
。
您在第一个程序中观察到的效果可能是
free()
不会将内存返回给操作系统。