C指针分配指针

时间:2015-01-22 06:33:44

标签: c pointers memory-management malloc

我的代码有效,但我不太明白为什么。我正在分配一个带字符串的指针,将该字符串传递给一个函数,然后对其进行修改。我很困惑,即使输入的字符串远远大于原始字符串,它似乎运行正常。我希望它会抱怨覆盖内存,特别是因为原始指针不是MALLOC / CALLOCed。

void changeArray(char *(*anArray)[3]);

功能声明

char *testArray[] = { "This is a test", "A Second Test", "A Third Test" };

指针声明&初始化

    changeArray(&testArray);

函数调用

void changeArray(char *(*anArray)[3]){
char userName[200];
printf("What is your name?:\t");
scanf("%199[^\n]s", userName);
*anArray[0] = userName; }

功能

    printf("Your name is: %s\n", testArray[0]);

在main中打印结果。

为什么testArray [0]能够接受新字符串而不为其重新分配内存?更令人费解的是我在本地人看到的结果并且它看起来已损坏,但仍打印正常。

+       [0] 0x00e2f850 "D`\x3\x1 øâ"    char *

我知道询问有关工作代码的问题很奇怪,但我需要确保理解发生了什么,以便我以后能够正确实施/避免它。

3 个答案:

答案 0 :(得分:2)

你混淆了字符串和指针。 A'字符串' in C是内存中的字符数组,通常由指向数组开头的指针引用。所以当你宣布

char *testArray[] = { "This is a test", "A Second Test", "A Third Test" };

这将testArray声明为一个包含3个指针的数组,并将每个指针初始化为指向静态字符串(可能在只读内存中的字符数组)。

changeArray函数中,您有:

char userName[200];
printf("What is your name?:\t");
scanf("%199[^\n]s", userName);
*anArray[0] = userName;

这将创建一个新的本地字符数组,并使用用户输入(可能是它们的名称)填充它,然后将引用传递的数组中的第0个指针指向此局部变量的参数。一旦这个函数返回,堆栈帧将被释放,指针悬空(指向现在释放的堆栈帧),因此它似乎可以工作但似乎随机变化。

指出,在它所在的范围退出之后访问这样的局部变量是未定义的行为。

答案 1 :(得分:0)

你在这里看到的是未定义的行为。

userName中有一个本地数组void changeArray(),你有一个指向它的指针,它只在函数内有效,一旦你从函数返回,释放分配给这个本地数组的内存就这样访问超出其范围的此位置未定义。你甚至可能会看到崩溃

答案 2 :(得分:0)

这是未定义的行为,未定义的行为在某些情况下按预期工作是合法的(并且在其他情况下可能会失败)。

在您的情况下,您将在函数中的堆栈上分配userName。当函数返回时,userName占用的内存通常保持不变。但绝对不能保证。下一个函数调用可能会破坏你的字符串。异步信号处理程序也可能破坏你的字符串,即使在函数返回和main()中下一行的执行之间也会发生这种情况。

然而,未定义的行为是完全未定义的,并且您的程序完全有权在执行时擦除您的硬盘。因此,尽量无条件地避免未定义的行为。