次のコードが機能しないのはなぜだろうと思っていました
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
test = "testingonly";
free(test);
}
それについて考えた後、私は最初にメモリ内の12文字にスペースを割り当てるが、次の行の割り当てがスタック上にchar配列を作成し、そのメモリアドレスがテストに渡されると仮定しました。したがって、free()は許可されていないスタック上のスペースを解放しようとします。あれは正しいですか?
それでは、ヒープに文字列を保存する正しい方法は何でしょうか?以下は一般的な方法ですか?
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
free(test);
}
char *test = (char*) malloc(12*sizeof(char));
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|x|x|x|x|x|x|x|x|x|x|x|x| (uninitialized memory, heap)
+-+-+-+-+-+-+-+-+-+-+-+-+
test = "testingonly";
+-+-+-+-+-+-+-+-+-+-+-+-+
test + |x|x|x|x|x|x|x|x|x|x|x|x|
| +-+-+-+-+-+-+-+-+-+-+-+-+
| +-+-+-+-+-+-+-+-+-+-+-+-+
+->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
free(test); // error, because test is no longer pointing to allocated space.
ポインタtest
を変更する代わりに、文字列"testingonly"
を割り当てられた場所にコピーする必要があります。 strcpy
またはstrdup
を使用します。使用可能なメモリが不十分な場合、malloc
やstrdup
などの関数はNULL
を返すため、チェックする必要があります。
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
または
char *test = strdup("testingonly");
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
あなたはすでにあなたの質問に答えました。基本的に、strcpyは文字列をコピーする適切な方法です。
最初のバージョンはスタック上に文字列を作成しませんが、割り当て後にfree
を許可しないことは正しいです。文字列リテラルは通常、メモリの定数/読み取り専用セクションに保存されます。割り当ては何もコピーせず、test
がそのメモリ領域を指すようにします。解放できません。その文字列を変更することもできません。
2番目のコードは正しくて普通です。実装にそれがある場合は、strdup
も調べてください。
さてあなたは正しいです。ここで、最初のコードを調べてみましょう。
char *test = (char*) malloc(12*sizeof(char));
上記のコードは問題ありません。
test = "testingonly";
ここでは、メモリリークにつながるポインタtest
を変更しました。そして、解放しようとすると、実際に割り当てられたポインターではなく、1つの「testingonly」リテラルが指しているのを解放します。リテラルは、通常のシナリオではオーバーライドできない定数メモリを指します。
2番目のコードについては、リテラルが存在する場所からデータを明示的にコピーして、test
が指しているヒープに正常に機能します。
2番目の点まではいstrcpy
は通常の方法です。生バイトをコピーする場合、他の方法は「memcpy」です。
注:リテラルはスタックに保存されません。ただし、リテラルが保存されている場所は変更できません。
コード
#include <stdio.h>
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
printf("string is: %s\n",test);
free(test);
return 0;
}
働くでしょう
これはメモリを割り当てるためのものです:
char *string;
string = (char *) malloc(15);
これはデータを保存するためのものです:
strcpy(str, "kavitajain");
printf("String = %s, Address = %u\n", str, str);