函数内部没有 malloc,怎么办?
free of malloc inside the function, how to do that?
我在 str 函数中创建了 malloc,我想释放这个 malloc 变量
#include <stdio.h>
char *str(void)
{
// create the malloc
char *string = malloc(2); // how to free it
*(string + 0) = 'J';
*(string + 1) = 'O';
// return the malloc
return string;
}
int main(void)
{
// print the function
printf("%s, str());
return 0;
}
free(string)
会释放它。但是要 print
它作为一个字符串,你必须在最后有 [=15=]
。
注意:如果您计划在函数调用结束时 return 它,则不应在函数内部释放它。因为这可能会导致未定义的行为。
正确的做事方式:
char *str(void)
{
// create the malloc
char *string = malloc(3); // how to free it
if(string){
*(string + 0) = 'J';
*(string + 1) = 'O';
*(string + 2) = '[=11=]';
// return the malloc
}
return string;
}
int main(void)
{
// print the function
char *s = str();
if(s)
printf("%s", s);
free(s);
return 0;
}
不正确
如果你这样做,那将是内存泄漏:
int main(void)
{
// print the function
printf("%s", str());
return 0;
}
如果您这样做,那么当您尝试将其打印出来时就会出现未定义的行为。
char *str(void)
{
// create the malloc
char *string = malloc(2); // how to free it
*(string + 0) = 'J';
*(string + 1) = 'O';
// return the malloc
free(string);
return string;
}
int main(void)
{
// print the function
printf("%s", str()); // undefined behavior. A dragon might appear.
return 0;
}
通常让调用者提供打印缓冲区是更好的选择;如果打印确实成功,可以通过 return 值提示;新的函数签名可能如下所示:
#include <stdbool.h>
bool str(size_t length, char buffer[length])
{
if(length < 3)
{
// buffer is too short...
return false;
}
buffer[0] = 'J';
buffer[1] = 'O';
buffer[2] = 0; // terminating null character, which you ommitted!
}
注意忽略数组参数中的长度说明符(函数参数仅!),定义等同于char buffer[]
或char* buffer
;仍然指定长度可以用来告诉用户实际需要什么样的参数(-> 自文档代码);还要注意,这仅适用于 outer-most 维度(在 char[12][10]
中 12
被忽略但不是 10,参数类型是等同于 char(*)[10]
,它是一个指向长度为 10 的数组的指针。
然后用户可以在堆或堆栈上动态分配字符串的位置:
int main(void)
{
char stack[3];
if(str(sizeof(stack), stack))
{
printf("%s", stack);
}
size_t len = 3;
char* heap = malloc(len);
if(!heap) // should always be checked!
{
// allocation failed!
return -1;
}
if(str(len, heap))
{
printf("%s", heap);
}
free(heap);
return 0;
}
如果您仍想保留原始签名,那么您需要 returned 字符串两次,一次打印它,一次释放它——也就是说,您需要将它存储在一个中间变量中以便能够这样做:
int main(void)
{
char* s = str(); // store it in a variable!
printf("%s", s); // still need to append the null terminator for!!!
free(s); // now you can free it
return 0;
}
如果您不附加空终止符,那么您需要明确限制要打印到控制台的字符数:
printf("%.2s", s);
// ^^ (!)
我在 str 函数中创建了 malloc,我想释放这个 malloc 变量
#include <stdio.h>
char *str(void)
{
// create the malloc
char *string = malloc(2); // how to free it
*(string + 0) = 'J';
*(string + 1) = 'O';
// return the malloc
return string;
}
int main(void)
{
// print the function
printf("%s, str());
return 0;
}
free(string)
会释放它。但是要 print
它作为一个字符串,你必须在最后有 [=15=]
。
注意:如果您计划在函数调用结束时 return 它,则不应在函数内部释放它。因为这可能会导致未定义的行为。
正确的做事方式:
char *str(void)
{
// create the malloc
char *string = malloc(3); // how to free it
if(string){
*(string + 0) = 'J';
*(string + 1) = 'O';
*(string + 2) = '[=11=]';
// return the malloc
}
return string;
}
int main(void)
{
// print the function
char *s = str();
if(s)
printf("%s", s);
free(s);
return 0;
}
不正确
如果你这样做,那将是内存泄漏:
int main(void)
{
// print the function
printf("%s", str());
return 0;
}
如果您这样做,那么当您尝试将其打印出来时就会出现未定义的行为。
char *str(void)
{
// create the malloc
char *string = malloc(2); // how to free it
*(string + 0) = 'J';
*(string + 1) = 'O';
// return the malloc
free(string);
return string;
}
int main(void)
{
// print the function
printf("%s", str()); // undefined behavior. A dragon might appear.
return 0;
}
通常让调用者提供打印缓冲区是更好的选择;如果打印确实成功,可以通过 return 值提示;新的函数签名可能如下所示:
#include <stdbool.h>
bool str(size_t length, char buffer[length])
{
if(length < 3)
{
// buffer is too short...
return false;
}
buffer[0] = 'J';
buffer[1] = 'O';
buffer[2] = 0; // terminating null character, which you ommitted!
}
注意忽略数组参数中的长度说明符(函数参数仅!),定义等同于char buffer[]
或char* buffer
;仍然指定长度可以用来告诉用户实际需要什么样的参数(-> 自文档代码);还要注意,这仅适用于 outer-most 维度(在 char[12][10]
中 12
被忽略但不是 10,参数类型是等同于 char(*)[10]
,它是一个指向长度为 10 的数组的指针。
然后用户可以在堆或堆栈上动态分配字符串的位置:
int main(void)
{
char stack[3];
if(str(sizeof(stack), stack))
{
printf("%s", stack);
}
size_t len = 3;
char* heap = malloc(len);
if(!heap) // should always be checked!
{
// allocation failed!
return -1;
}
if(str(len, heap))
{
printf("%s", heap);
}
free(heap);
return 0;
}
如果您仍想保留原始签名,那么您需要 returned 字符串两次,一次打印它,一次释放它——也就是说,您需要将它存储在一个中间变量中以便能够这样做:
int main(void)
{
char* s = str(); // store it in a variable!
printf("%s", s); // still need to append the null terminator for!!!
free(s); // now you can free it
return 0;
}
如果您不附加空终止符,那么您需要明确限制要打印到控制台的字符数:
printf("%.2s", s);
// ^^ (!)