释放 void 指针数组的元素
Freeing elements of a void pointer array
我正在调试其他人编写的一些代码,Valgrind 检测到有多个内存泄漏。我认为导致问题的部分代码涉及 void
指针:
int noElements = 100;
void** ptr = malloc( noElements * sizeof(void*));
for(int i = 0; i < noElements; i++)
{
ptr[i] = malloc(sizeof(void*));
}
//Operation filling the array and doing calculation
free(ptr); //This will not clear the underlying array causing the memory leak?
我创建了一个小测试程序来检查错误是否在我认为的位置(在调用 free(ptr);
之前没有释放每个 ptr[i]
),但是我在尝试释放元素时遇到错误。我的测试程序如下所示:
int main()
{
int num = 10000000; //Large array so I can clearly see memory usage
void** ptr = (void**) malloc(sizeof(void*) * num);
for (int i = 0; i < num; i++)
{
ptr[i] = malloc(sizeof(void*));
ptr[i] = &i; //If I never point elements at anything, this code works
}
for (int i = 0; i < num; i++)
{
free(ptr[i]); //Crashes here if the elements have been pointed at a variable
}
free(ptr);
return 0;
}
如果实际上已经分配了指针,为什么在每个数组元素上调用 free 会导致程序崩溃?
在你的代码中
ptr[i] = &i;
产生三个问题。
- 它使
malloc()
实际返回的指针丢失(你正在覆盖它),所以你没有机会在 free()
-稍后编辑它,导致 memory leak.
i
是局部作用域变量(for
循环体的作用域),并且您正在存储要在作用域外使用的变量的地址(即,在生命周期结束后)。在范围之外尝试访问它的地址将调用 undefined behavior.
- (Ignoring point 2) Attempt to
free()
the ptr[i]
will cause undefined behavior again, as the pointer is not returned by memory分配器函数。
你的指针被分配了一个不是你想要的值。
for (int i = 0; i < num; i++)
{
ptr[i] = malloc(sizeof(void*));
ptr[i] = &i; //If I never point elements at anything, this code works
}
首先,您分配一个由 malloc()
返回的有效内存地址。
使用 free()
可以免费使用此地址。
但是随后您分配了另一个地址。您的局部变量的地址 i
。此内存位置未使用 malloc()
分配,因此无法释放。通过分配此地址,您丢失了导致内存泄漏的动态分配地址。
您的评论有误。您已经分配了一个 ptr[i]
指向某个有效地址的值。您无需再次分配。而你不应该。
我正在调试其他人编写的一些代码,Valgrind 检测到有多个内存泄漏。我认为导致问题的部分代码涉及 void
指针:
int noElements = 100;
void** ptr = malloc( noElements * sizeof(void*));
for(int i = 0; i < noElements; i++)
{
ptr[i] = malloc(sizeof(void*));
}
//Operation filling the array and doing calculation
free(ptr); //This will not clear the underlying array causing the memory leak?
我创建了一个小测试程序来检查错误是否在我认为的位置(在调用 free(ptr);
之前没有释放每个 ptr[i]
),但是我在尝试释放元素时遇到错误。我的测试程序如下所示:
int main()
{
int num = 10000000; //Large array so I can clearly see memory usage
void** ptr = (void**) malloc(sizeof(void*) * num);
for (int i = 0; i < num; i++)
{
ptr[i] = malloc(sizeof(void*));
ptr[i] = &i; //If I never point elements at anything, this code works
}
for (int i = 0; i < num; i++)
{
free(ptr[i]); //Crashes here if the elements have been pointed at a variable
}
free(ptr);
return 0;
}
如果实际上已经分配了指针,为什么在每个数组元素上调用 free 会导致程序崩溃?
在你的代码中
ptr[i] = &i;
产生三个问题。
- 它使
malloc()
实际返回的指针丢失(你正在覆盖它),所以你没有机会在free()
-稍后编辑它,导致 memory leak. i
是局部作用域变量(for
循环体的作用域),并且您正在存储要在作用域外使用的变量的地址(即,在生命周期结束后)。在范围之外尝试访问它的地址将调用 undefined behavior.- (Ignoring point 2) Attempt to
free()
theptr[i]
will cause undefined behavior again, as the pointer is not returned by memory分配器函数。
你的指针被分配了一个不是你想要的值。
for (int i = 0; i < num; i++)
{
ptr[i] = malloc(sizeof(void*));
ptr[i] = &i; //If I never point elements at anything, this code works
}
首先,您分配一个由 malloc()
返回的有效内存地址。
使用 free()
可以免费使用此地址。
但是随后您分配了另一个地址。您的局部变量的地址 i
。此内存位置未使用 malloc()
分配,因此无法释放。通过分配此地址,您丢失了导致内存泄漏的动态分配地址。
您的评论有误。您已经分配了一个 ptr[i]
指向某个有效地址的值。您无需再次分配。而你不应该。