私はmallocとfree qをしなければならないと思います。しかし関数 "return q"。それはそれがそれ自身の記憶にq値を記憶することを意味しない。したがって、関数の実行後もデータは保存されますか?
いいえ、データは保存されません。実際、あなたのポインタqが割り当てられていない状態で使用されていると、問題が発生することがあります。また、この関数の実行が完了すると、変数char * qが破棄されます。
@ Michaelの答えで示唆されているようにデータをコピーする前にポインタqにメモリを割り当てる必要があります。しかし、この関数でデータを返すと、割り当てられたメモリを手動で解放する必要があります。原因メモリリーク
使用することが適切である
char *strdup(const char *p) // From @Michael's answer
{
char *q;
q = malloc(strlen(p) + 1);
if(NULL != q)
strcpy(q, p);
return q;
}
void someFunction()
{
char* aDupString = strdup("Hello World!!!");
/*... somecode use aDupString */
free(aDupString); // If not freed, will cause memory leaks
}
を(メモリが割り当てられたが、何のポインタを使用すると、割り当てられたメモリのチャンクを参照していないので、プログラムの実行全体にアクセスできなくなりますが存在している状況) malloc? mallocが必要な他の状況はありますか?
以下の状況で使用することが適切である:
1>配列の使用サイズは、コンパイル時に知られていません。
2>サイズの柔軟性が必要です。たとえば、関数は小さなデータサイズと大きなデータサイズで動作する必要があります。 (データ構造のようなリンクリスト、スタック、キュー、などなど)
私がこれまで理解したように、私は新しい変数私は関数内で宣言された変数がすることを必要とするたびにをmallocしなければならないということです他の場所で使用されています。本当?
私はこれが部分的に真実だと思います。あなたが何をしようとしているかによって、mallocを使って周りを回る方法があるかもしれません。たとえば、あなたのストルードは次のように書き直すこともできます:
void strdup2(const char *p, char* strOut)
{
// malloc not require
strcpy(strOut, p);
}
void someFunction()
{
char aString[15] = "Hello World!!!";
char aDupStr[sizeof(aString)];
strdup2(aString, aDupStr);
// free() memory not required. but size is not dynamic.
}
まあ、 'strcpy'の呼び出しを見てください。 'p'が指す文字列を' q'が指す配列にコピーしようとしています。 'q'は配列を指すように初期化されていません。これにはガーベッジ・バリューが含まれているため、これを呼び出すとメモリが破壊されます。まず、 'malloc'が返すもののような適切な記憶域のアドレスに' q'を設定する必要があります。そのときだけ、そのターゲットに書き込むことができます。シンプル。 –
qはアドレスですが、初期化されていません。 strcpyはデータを取得してqで指定された場所に配置しようとしていますが、qは有効なものを指していません。 mallocを呼び出す(そして結果をqに代入する)と、qはデータを置く場所を指します。 –
*本物の問題は、あなたが生涯について知る必要があるということです。残念なことに、ほとんどのチュートリアルでは重要な問題ではなく、構文のみを教えています。 – o11c