C 从改变指针地址的函数返回,地址保持不变
我编写了一个更复杂的程序,但我已将问题缩小到以下方面: 为什么这个程序打印的是垃圾而不是hzllo?我用调试器跟踪了temp和p的值和内存地址,它从foo函数正确返回,原因我不明白C 从改变指针地址的函数返回,地址保持不变,c,visual-studio,C,Visual Studio,我编写了一个更复杂的程序,但我已将问题缩小到以下方面: 为什么这个程序打印的是垃圾而不是hzllo?我用调试器跟踪了temp和p的值和内存地址,它从foo函数正确返回,原因我不明白 void foo(char **str) { char temp[79]; strcpy_s(temp,79,*str); *(temp + 1) = 'z'; *str = temp; } void main() { char *p = (char*) mal
void foo(char **str) {
char temp[79];
strcpy_s(temp,79,*str);
*(temp + 1) = 'z';
*str = temp;
}
void main() {
char *p = (char*) malloc(79 * sizeof(char));
p = "hello";
foo(&p);
printf("%s", p);
}
temp
是一个局部变量,当您退出foo
时,该变量超出范围。因此p
是一个悬空指针,您的程序具有未定义的行为。更改
char temp[79]; # allocated on the stack, vanishes on return
…到
static char temp[79]; # has a longer lifetime
此外,您不需要malloc(3)
这样更好:
void foo(char **str) {
// This should change the pointer ... to something valid outside the function
*str = (*str) + 1;
}
您是否意识到,
main
的第一行除了产生即时内存泄漏之外,什么都不做?(malloc确实属于函数foo
!)谢谢,这很有效。但我还有一个问题。为什么我需要将temp定义为静态?我明白,试图通过值调用是行不通的,因为temp是本地的。所以我通过引用调用,为什么这还不够?@Kerrek,当然是真的,虽然OP现在正在寻找启发,而不是研究生院,所以,一步一个脚印。他显然想通过双重间接寻址来修改指针,这是一个合理的教训。@Steinfeld,您的ref调用非常正确,运行良好。问题是:你指的是什么?你用的是当地人的地址。它的生命周期仅限于函数调用实例的持续时间。具体来说,它是在堆栈上分配的。当函数返回时,所有内容都从堆栈中弹出,该内存将在下一次函数调用时重用,这将是printf()
实例。如果希望它在foo()
返回后仍然存在,则需要更持久的东西。很抱歉,我无法理解您的答案。我试图指出两点:1)返回指向“temp”的指针是邪恶的,2)它显示了一个更改指针的示例*str=(*str)+1
导致“p”指向“ello”(而不是“hello”)。
void foo(char **str) {
// This should change the pointer ... to something valid outside the function
*str = (*str) + 1;
}