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*
作为第二个参数的原因。嗯,有点像。可以添加保守的