释放返回变量内存的正确方法
Proper Way to Free Memory of a Returned Variable
我创建了一个旨在获取用户输入的函数。它要求将内存分配给保存用户输入的变量;但是,该变量在函数末尾被 returned。释放分配的 memory/return 变量值的正确方法是什么?
代码如下:
char *input = malloc(MAX_SIZE*sizeof(char*));
int i = 0;
char c;
while((c = getchar()) != '\n' && c != EOF) {
input[i++] = c;
}
return input;
我是否应该return输入的地址并在使用后释放它?
想知道释放输入变量的最合适方法。
很简单,只要把malloc()
所return的同一个指针传给free()
就可以了。
例如
char *readInput(size_t size)
{
char *input;
int chr;
input = malloc(size + 1);
if (input == NULL)
return NULL;
while ((i < size) && ((chr = getchar()) != '\n') && (chr != EOF))
input[i++] = chr;
input[size] = '[=10=]'; /* nul terminate the array, so it can be a string */
return input;
}
int main(void)
{
char *input;
input = readInput(100);
if (input == NULL)
return -1;
printf("input: %s\n", input);
/* now you can free it */
free(input);
return 0;
}
你永远不应该做的是
free(input + n);
因为input + n
不是malloc()
的指针return。
但是您的代码还有其他问题需要您注意
您正在为 MAX_SIZE
char
分配 space,因此您应该乘以 sizeof(char)
,即 1
,而不是sizeof(char *)
会分配 MAX_SIZE
指针,你也可以让 MAX_SIZE
成为一个函数参数,因为如果你分配一个固定缓冲区,你可以在 main()
中定义一个数组大小为MAX_SIZE
,如char input[MAX_SIZE]
,并将其作为参数传递给readInput()
,从而避免了malloc()
和free()
.
你分配了那么多 space 但你没有阻止 while
循环中的溢出,你应该验证 i < MAX_SIZE
.
您可以使用 return 类型 char*
、return input
编写函数,并要求用户在完成后调用 free
数据.
您还可以要求用户自己传入大小合适的缓冲区,以及缓冲区大小限制,以及return写入缓冲区的字符数。
这是一个经典的c案例。函数为其结果分配内存,调用者必须释放返回值。你现在正走在 c 内存泄漏的薄冰上。 2 个原因
首先;您无法以可执行的方式传达免费要求(即编译器或运行时无法帮助您 - 与指定参数类型形成对比)。你只需要在某处记录它并希望调用者已经阅读你的文档
其次:即使调用者知道释放结果,他也可能会犯错误,一些错误路径会被采用而不会释放内存。这不会立即导致错误,一切似乎都正常,但是在 运行 3 周后,您的应用程序在 运行 内存不足
后崩溃
这就是为什么这么多 'modern' 语言关注这个主题的原因,c++ 智能指针、Java、C# 等垃圾收集,...
我创建了一个旨在获取用户输入的函数。它要求将内存分配给保存用户输入的变量;但是,该变量在函数末尾被 returned。释放分配的 memory/return 变量值的正确方法是什么?
代码如下:
char *input = malloc(MAX_SIZE*sizeof(char*));
int i = 0;
char c;
while((c = getchar()) != '\n' && c != EOF) {
input[i++] = c;
}
return input;
我是否应该return输入的地址并在使用后释放它?
想知道释放输入变量的最合适方法。
很简单,只要把malloc()
所return的同一个指针传给free()
就可以了。
例如
char *readInput(size_t size)
{
char *input;
int chr;
input = malloc(size + 1);
if (input == NULL)
return NULL;
while ((i < size) && ((chr = getchar()) != '\n') && (chr != EOF))
input[i++] = chr;
input[size] = '[=10=]'; /* nul terminate the array, so it can be a string */
return input;
}
int main(void)
{
char *input;
input = readInput(100);
if (input == NULL)
return -1;
printf("input: %s\n", input);
/* now you can free it */
free(input);
return 0;
}
你永远不应该做的是
free(input + n);
因为input + n
不是malloc()
的指针return。
但是您的代码还有其他问题需要您注意
您正在为
MAX_SIZE
char
分配 space,因此您应该乘以sizeof(char)
,即1
,而不是sizeof(char *)
会分配MAX_SIZE
指针,你也可以让MAX_SIZE
成为一个函数参数,因为如果你分配一个固定缓冲区,你可以在main()
中定义一个数组大小为MAX_SIZE
,如char input[MAX_SIZE]
,并将其作为参数传递给readInput()
,从而避免了malloc()
和free()
.你分配了那么多 space 但你没有阻止
while
循环中的溢出,你应该验证i < MAX_SIZE
.
您可以使用 return 类型 char*
、return input
编写函数,并要求用户在完成后调用 free
数据.
您还可以要求用户自己传入大小合适的缓冲区,以及缓冲区大小限制,以及return写入缓冲区的字符数。
这是一个经典的c案例。函数为其结果分配内存,调用者必须释放返回值。你现在正走在 c 内存泄漏的薄冰上。 2 个原因
首先;您无法以可执行的方式传达免费要求(即编译器或运行时无法帮助您 - 与指定参数类型形成对比)。你只需要在某处记录它并希望调用者已经阅读你的文档
其次:即使调用者知道释放结果,他也可能会犯错误,一些错误路径会被采用而不会释放内存。这不会立即导致错误,一切似乎都正常,但是在 运行 3 周后,您的应用程序在 运行 内存不足
后崩溃这就是为什么这么多 'modern' 语言关注这个主题的原因,c++ 智能指针、Java、C# 等垃圾收集,...