1

私はいくつかのコードを持っています:

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からメモリを解放できますか?例えば:

temp=itoa(i);
mvwprintw(my_menu_win,i+1,2,temp);
free(temp);
4

4 に答える 4

3

要するに:いいえ。

割り当てられたメモリを解放するには、そのメモリへの参照が必要です。

変換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));
于 2012-11-05T11:37:01.713 に答える
0

いくつかの問題:

関数itoaが誤ってコンパイルされます。の配列へのポインターは へのポインターとcharは異なる型charであり、これは警告をスローしますが、*t代わりにt. の型tが「16 要素配列へのポインタchar」であるとすると、式の*t型は「16 要素配列char」になります。sizeof_Alignof、または単項演算子のオペランドである場合、または宣言で別の配列を初期化するために使用される文字列リテラルである場合を除いて&、型 "N 要素配列 " の式はT変換 ("decay") されます。型「へのポインタ」の式T"、その値は配列の最初の要素のアドレスになります。したがって、誤って正しい型を返しています。

malloc(少なくとも C89 では)の結果をキャストする必要はありません。malloc通話の典型的なテンプレートを次に示します。

T *p = malloc(N * sizeof *p);

は、割り当てているN型の要素の数です。Tしたがって、呼び出しを次のように書き換えることができます

char *t = malloc(16 * sizeof *t);

ただし、この特定のケースでsizeofは == 1 であるため、冗長sizeof charです。その後、コードの残りの部分は次のようになります。

sprintf(t, "%d", a);
return t;

その後のある時点でfree、 の実装によって返された値を呼び出すことになりますitoa。率直に言って、C99 以降のコンパイラを使用している場合は、Jens Gustedt のソリューションの方が優れています。

于 2012-11-05T13:53:57.973 に答える
0

それを行う別の方法は、関数に静的配列を割り当てることです。この方法では、それを解放する必要はまったくありません。

const char* itoa(int a)
{
    static char t[16];
    sprintf(t,"%d",a);
    return t;
}

mvwprintw(my_menu_win,i+1,2,itoa(i));

ノート:

この方法はスレッドセーフではなく、関数の引数として複数回使用することはできません。

于 2012-11-05T11:46:14.103 に答える