質問1:
テスト機能を実行すると結果はどうなりますか?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void GetMemory(char* p)
{
p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
test();
return 0;
}
問題分析: このコードはクラッシュします。
str を関数 GetMemory に渡し、str に対して動的メモリ割り当てを実行します。このとき、str は空間 p を指します。現時点では p は単なる仮パラメータであることに注意してください。そのため、プログラムが関数を終了するときにGetMemory、str の値は変更されません。変更があった場合、同時に動的に割り当てられたメモリ p は再利用されず、メモリ リーク。
プログラムは strcpy 関数に入ります。この時点では、str は NULL です。この時点でも、strcpy 関数は str を逆参照します。NULL ポインタを逆参照すると、プログラムがクラッシュしました。
解決策: str のアドレスを渡し、char**p を使用してそれを受け取ります。この方法では、str 用のスペースを効果的に開くことができます。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void GetMemory(char** p)
{
*p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
Test();
return 0;
}
操作結果:
質問2:
テスト機能を実行すると結果はどうなりますか?
char* GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char* str = NULL;
str = GetMemory();
printf(str);
}
int main()
{
test();
return 0;
}
問題分析: このコードは依然として望ましい結果を得ることができません。
GetMemory 関数に str を渡しました。GetMemory 関数は空間 p を開きましたが、p はスタック領域に存在します。スタック領域のデータは関数呼び出し中にのみ有効であることに注意してください。関数の戻り値、スタック フレームがポップされると、スタック領域のデータは破棄されます。 p のアドレスが渡されたとしても、str は p 空間のアドレスを見つけることができますが、p 内のデータは破壊されています。
解決:
1. static を使用して p を変更し、p を静的変数にすることができます。静的変数にはグローバルなライフサイクルがあります。静的変数はプログラムの実行中に存在し、関数が呼び出されて返されるときに作成および破棄されることはありません。
2. もちろん、malloc を使用してスペースを空けることも可能です。
質問 3:
テスト機能を実行すると結果はどうなりますか?
void GetMemory(char** p, int num)
{
*p = (char*)malloc(num);
}
void Test(void)
{
char* str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
int main()
{
Test();
return 0;
}
質問分析: このコードには問題もあり、malloc によって開かれたスペースが解放されず、メモリ リークの問題が発生します。
void GetMemory(char** p, int num)
{
*p = (char*)malloc(num);
}
void Test(void)
{
char* str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
free(str);
str = NULL;
}
int main()
{
Test();
return 0;
}
これが正しい書き方です。
質問4:
テスト機能を実行すると結果はどうなりますか?
void Test(void)
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
int main()
{
Test();
return 0;
}
問題分析: このコードにも問題があります。
str は解放されていますが、空にはなっていないことがわかります。その結果、str はまだ malloc によって開かれた領域を指しているため、ワイルド ポインタの問題が発生します。次に、strcpy は str が指す空間にアクセスしますが、str が指す空間は解放されているため、不正なメモリ アクセスが発生します。