ポインタパラメータ転送メモリ

1673 ワード

関数のパラメータはポインタです.このポインタでダイナミックメモリを申請しないでください.
void get_memory(char *p, int num)
{
	p = (char *)malloc(sizeof(char) * num);	
}

void main(void)
{
	char *str = NULL;
	str = get_memory(str, 20);
	strcpy(str, "Hello, world");
}

strは相変わらずNULLを得ることができます.
コンパイラは常に各関数のパラメータに一時的なコピーを提供し、ポインタパラメータpのコピーは_p,コンパイラ使_p=p、関数内のプログラムが変更されたら_pが指すコンテンツは、同様に、パラメータpが指すコンテンツも対応する修正(同じメモリ領域を指す)を行う.これもポインタが出力パラメータとして使用できる理由です.しかし前例では_pは新しいメモリを申請しましたが、ただ_p自体の値は、新しいメモリ領域を指すように変更されたが、p自体は少しも変更されていない(すなわち、_pが指すオブジェクトではなく、_p自体の値を変更する).
解決策
(1)ポインタへのポインタまたはポインタへの参照
void get_memory(char **p, int num)
{
	*p = (char *)malloc(sizeof(char) * num);   //               ,            
}

void test1(void)
{
	char *str = NULL;
	str = get_memory(&str, 20);
	strcpy(str, "Hello world");
	cout<

(2)関数戻り値はダイナミックメモリを渡す(ただしreturn文は「スタックメモリ」へのポインタまたは参照を返すことはできません.このメモリは関数の終了時に自動的に解放されるためです).
char *get_string(void)
{
	char p[] = "Hello world";   //  ,           ,           
	return p;
}

void test(void)
{
	char *str = NULL;
	str = get_string();
	cont<

デバッグの上の例を追跡すると、strがNULLではないことがわかります.しかしstrの内容も「Hello world」ではなく、ゴミです.
char *get_string1(void)
{
	char *p = "Hello world";
	return p;
}

void test2(void)
{
	char *str = NULL;
	str = get_string1();
	cout<

上記の例ではエラーはありませんが、pが指す静的記憶領域であり、「Hello world」は文字列定数であり、そのライフサイクルはプログラムが終了する前に常に有効であり、いつget_を呼び出すかにかかわらずstring 1()は、常に同じ「読み取り専用メモリ領域」を返し、変更しようとしないため、戻り値をconst char*タイプに変更して、プログラムが文字列定数を意図的に変更しないようにすることができます.