malloc'ing 和 realloc'ing 指针导致内存泄漏 return
malloc'ing and realloc'ing pointers causing memory leaks on return
我被告知要编写一个包装器,它采用位置的起始地址和大小的数字 'n'。以后用这个内存存点东西。
我能够编写代码,但程序中存在内存泄漏。
这是程序:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int alloc_func(char *newptr, int size)
{
newptr = (char *)realloc(newptr, size);
printf("In func: %p\n", newptr);
if(NULL == newptr)
return 0;
else
return 1;
}
int main(int argc, char **argv)
{
char *foo = "Computer"; //string to be copied to newly allocated memory
char *ptr = (char *)malloc(1*sizeof(char));
printf("Before return: %p\n", ptr);
int size = 10, flag;
flag = alloc_func(ptr, size);
printf("After return: %p\n", ptr);
if(flag == 0)
return EXIT_FAILURE;
else{
strcpy(ptr, foo);
}
printf("The copied string is: %s\n", ptr);
free(ptr);
return 0;
}
在 运行 valgrind 上,泄漏摘要说
"definitely lost: 10 bytes in 1 block"
发生这种情况是因为我将 ptr(起始地址)作为指针值发送给函数,因此函数正在创建指针的副本,即程序中的 newptr。这个 newptr 被重新分配到 10 个位置。由于我不返回 newptr,一旦函数结束,我的“重新分配”位置将超出范围并丢失。
我的疑问是:
a) 即使创建了指针的副本,ptr 和 newptr 也会指向相同的内存位置,那为什么会泄漏?
b) 不是 malloc 变量 'global' 吗?
c) 发生泄漏是因为我没有传递指针的地址以便不会创建副本吗? (我试过了,但我想知道为什么)
d) 在我的 main 中,什么是免费的(然后 ptr 在做什么)?只是清除为 1 分配的 ptr?
e) 有什么方法可以检查这 10 个“大小”字节的分配是否成功?
您的 alloc_func() 方法应该是:
int alloc_func(char **newptr, int size)
{
char *p = (char *)realloc(*newptr, size);
printf("In func: %p\n", p);
if(NULL == p) {
return 0;
} else {
*newptr = p;
return 1;
}
然后用
调用它
flag = alloc_func(&ptr, size);
这样 ptr 就会改变。
您正在更改 alloc_func
中 newptr
的值。然而,这只是局部变化。它不会更改调用函数中指针的值。结果,你有一个悬空指针和内存泄漏。
调用函数有悬空指针。
alloc_func
有内存泄漏。
您需要 return 从 alloc_func
到调用函数的新分配指针。您可以通过 returned 值或将参数更改为指向指针的指针来实现。
方案一:Return一个指针
char* alloc_func(char *newptr, int size)
{
newptr = (char *)realloc(newptr, size);
printf("In func: %p\n", newptr);
return newptr;
}
并将 main
中的调用更改为:
ptr = alloc_func(ptr, size); // not flag = ...
解决方案 2:更改参数类型
int alloc_func(char **newptr, int size)
{
*newptr = (char *)realloc(*newptr, size);
printf("In func: %p\n", *newptr);
if(NULL == *newptr)
return 0;
else
return 1;
}
并将 main
中的调用更改为:
flag = alloc_func(&ptr, size); // Use &ptr, not ptr
我被告知要编写一个包装器,它采用位置的起始地址和大小的数字 'n'。以后用这个内存存点东西。 我能够编写代码,但程序中存在内存泄漏。 这是程序:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int alloc_func(char *newptr, int size)
{
newptr = (char *)realloc(newptr, size);
printf("In func: %p\n", newptr);
if(NULL == newptr)
return 0;
else
return 1;
}
int main(int argc, char **argv)
{
char *foo = "Computer"; //string to be copied to newly allocated memory
char *ptr = (char *)malloc(1*sizeof(char));
printf("Before return: %p\n", ptr);
int size = 10, flag;
flag = alloc_func(ptr, size);
printf("After return: %p\n", ptr);
if(flag == 0)
return EXIT_FAILURE;
else{
strcpy(ptr, foo);
}
printf("The copied string is: %s\n", ptr);
free(ptr);
return 0;
}
在 运行 valgrind 上,泄漏摘要说 "definitely lost: 10 bytes in 1 block"
发生这种情况是因为我将 ptr(起始地址)作为指针值发送给函数,因此函数正在创建指针的副本,即程序中的 newptr。这个 newptr 被重新分配到 10 个位置。由于我不返回 newptr,一旦函数结束,我的“重新分配”位置将超出范围并丢失。
我的疑问是:
a) 即使创建了指针的副本,ptr 和 newptr 也会指向相同的内存位置,那为什么会泄漏?
b) 不是 malloc 变量 'global' 吗?
c) 发生泄漏是因为我没有传递指针的地址以便不会创建副本吗? (我试过了,但我想知道为什么)
d) 在我的 main 中,什么是免费的(然后 ptr 在做什么)?只是清除为 1 分配的 ptr?
e) 有什么方法可以检查这 10 个“大小”字节的分配是否成功?
您的 alloc_func() 方法应该是:
int alloc_func(char **newptr, int size)
{
char *p = (char *)realloc(*newptr, size);
printf("In func: %p\n", p);
if(NULL == p) {
return 0;
} else {
*newptr = p;
return 1;
}
然后用
调用它flag = alloc_func(&ptr, size);
这样 ptr 就会改变。
您正在更改 alloc_func
中 newptr
的值。然而,这只是局部变化。它不会更改调用函数中指针的值。结果,你有一个悬空指针和内存泄漏。
调用函数有悬空指针。
alloc_func
有内存泄漏。
您需要 return 从 alloc_func
到调用函数的新分配指针。您可以通过 returned 值或将参数更改为指向指针的指针来实现。
方案一:Return一个指针
char* alloc_func(char *newptr, int size)
{
newptr = (char *)realloc(newptr, size);
printf("In func: %p\n", newptr);
return newptr;
}
并将 main
中的调用更改为:
ptr = alloc_func(ptr, size); // not flag = ...
解决方案 2:更改参数类型
int alloc_func(char **newptr, int size)
{
*newptr = (char *)realloc(*newptr, size);
printf("In func: %p\n", *newptr);
if(NULL == *newptr)
return 0;
else
return 1;
}
并将 main
中的调用更改为:
flag = alloc_func(&ptr, size); // Use &ptr, not ptr