malloc后释放内存
我有一些代码:malloc后释放内存,c,malloc,C,Malloc,我有一些代码: char * itoa(int a) { char (*t)[16]=(char(*)[16])malloc(1*sizeof(char[16])); sprintf(*t,"%d",a); return *t; } // ... mvwprintw(my_menu_win,i+1,2,itoa(i)); 我可以从malloc中释放内存而不添加临时变量吗? e、 g: 简言之,没有 要释放分配的内存,需要对其进行引用 如果您可以更改转换API,可能的解决
char * itoa(int a)
{
char (*t)[16]=(char(*)[16])malloc(1*sizeof(char[16]));
sprintf(*t,"%d",a);
return *t;
}
// ...
mvwprintw(my_menu_win,i+1,2,itoa(i));
我可以从malloc中释放内存而不添加临时变量吗?
e、 g:
简言之,没有
要释放分配的内存,需要对其进行引用
如果您可以更改转换API,可能的解决方法是使用外部提供的缓冲区:
char * itoa(char * t, int i)
{
sprintf(t,"%d",a);
return t;
}
用这种方式调用itoa()
,然后:
{
char buffer [16];
mvwprintw(my_menu_win,i+1,2,itoa(buffer, i));
}
或者(仅C99)可以通过以下方式调用itoa()
:
mvwprintw(my_menu_win,i+1,2,itoa((char[16]){0}, i));
因此,要清理此问题,宏有助于:
#define ITOA_0(i) itoa((char[16]){0}, i) /* init array with 0s */
#define ITOA(i) itoa((char[16]){}, i) /* do not init array with 0s -> faster, but none ISO */
...
mvwprintw(my_menu_win,i+1,2,ITOA(i));
简言之,没有
要释放分配的内存,需要对其进行引用
如果您可以更改转换API,可能的解决方法是使用外部提供的缓冲区:
char * itoa(char * t, int i)
{
sprintf(t,"%d",a);
return t;
}
用这种方式调用itoa()
,然后:
{
char buffer [16];
mvwprintw(my_menu_win,i+1,2,itoa(buffer, i));
}
或者(仅C99)可以通过以下方式调用itoa()
:
mvwprintw(my_menu_win,i+1,2,itoa((char[16]){0}, i));
因此,要清理此问题,宏有助于:
#define ITOA_0(i) itoa((char[16]){0}, i) /* init array with 0s */
#define ITOA(i) itoa((char[16]){}, i) /* do not init array with 0s -> faster, but none ISO */
...
mvwprintw(my_menu_win,i+1,2,ITOA(i));
另一种方法是在函数中分配一个静态数组,这样就不必释放它:
const char* itoa(int a)
{
static char t[16];
sprintf(t,"%d",a);
return t;
}
mvwprintw(my_menu_win,i+1,2,itoa(i));
注:
这种方法不是线程安全的,不能多次用作函数的参数。另一种方法是在函数中分配一个静态数组,这样就不必释放它:
const char* itoa(int a)
{
static char t[16];
sprintf(t,"%d",a);
return t;
}
mvwprintw(my_menu_win,i+1,2,itoa(i));
注:
这种方式不是线程安全的,不能多次用作函数的参数。对于知道作用域受到限制的缓冲区,不应使用
malloc
对于可能需要保留缓冲区一段时间的情况,一个很好的解决方案是从C99开始的复合文本。我喜欢这样的东西
char const* itoa(int a, char (*buffer)[16]) {
sprintf(*buffer,"%d",a);
return *buffer;
}
#define ITOA(A) itoa((A), &(char[16]){ 0 })
指向函数数组的指针确保传递了包含
16个元素的缓冲区。对于已知范围受到限制的缓冲区,不应使用malloc
对于可能需要保留缓冲区一段时间的情况,一个很好的解决方案是从C99开始的复合文本。我喜欢这样的东西
char const* itoa(int a, char (*buffer)[16]) {
sprintf(*buffer,"%d",a);
return *buffer;
}
#define ITOA(A) itoa((A), &(char[16]){ 0 })
指向函数数组的指针可确保传递包含16个元素的缓冲区。几个问题:
您的itoa
函数是意外编译的。指向char
数组的指针与指向char
的指针的类型不同,如果不是因为您返回的是*t
而不是t
,这会引发警告。假设t
具有类型“指向char
的16元素数组的指针”,则表达式*t
具有类型“char
的16元素数组”。除非它是sizeof
、\u Alignof
或一元&
运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字,否则“N元素数组的T
”类型的表达式将被转换(“衰减”)为“指针指向T
”类型的表达式,它的值将是数组第一个元素的地址。所以你无意中返回了正确的类型
您不需要强制转换malloc的结果(至少从C89开始)。以下是malloc
调用的典型模板:
T *p = malloc(N * sizeof *p);
其中N
是您正在分配的T
类型的元素数。所以你可以把你的电话改写成
char *t = malloc(16 * sizeof *t);
尽管在这种特殊情况下,sizeof
是冗余的,因为sizeof char
==1。那么剩下的代码就是
sprintf(t, "%d", a);
return t;
然后,在稍后的某个时候,您将调用free
,处理itoa
实现返回的值。尽管坦率地说,如果使用C99或更高版本的编译器,Jens Gustedt的解决方案会更好 几个问题:
您的itoa
函数是意外编译的。指向char
数组的指针与指向char
的指针的类型不同,如果不是因为您返回的是*t
而不是t
,这会引发警告。假设t
具有类型“指向char
的16元素数组的指针”,则表达式*t
具有类型“char
的16元素数组”。除非它是sizeof
、\u Alignof
或一元&
运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字,否则“N元素数组的T
”类型的表达式将被转换(“衰减”)为“指针指向T
”类型的表达式,它的值将是数组第一个元素的地址。所以你无意中返回了正确的类型
您不需要强制转换malloc的结果(至少从C89开始)。以下是malloc
调用的典型模板:
T *p = malloc(N * sizeof *p);
其中N
是您正在分配的T
类型的元素数。所以你可以把你的电话改写成
char *t = malloc(16 * sizeof *t);
尽管在这种特殊情况下,sizeof
是冗余的,因为sizeof char
==1。那么剩下的代码就是
sprintf(t, "%d", a);
return t;
然后,在稍后的某个时候,您将调用free
,处理itoa
实现返回的值。尽管坦率地说,如果使用C99或更高版本的编译器,Jens Gustedt的解决方案会更好 要释放它,需要一个指向它的指针,为此需要一个变量来保存指针。另外,为什么char(*)[16]
而不是普通的char*
?作为旁注,您不应该强制转换malloc的结果这就是itoa
将char*
作为第二个参数的原因。嗯,有点像。可以向C添加保守的垃圾收集,然后不需要任何显式调用来释放它:要释放它,需要一个指向它的指针,因此需要一个变量来保存指针。另外,为什么char(*)[16]
而不是普通的char*
?作为旁注,您不应该强制转换malloc的结果这就是itoa
将char*
作为第二个参数的原因。嗯,有点像。可以添加保守的