Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从改变指针地址的函数返回,地址保持不变_C_Visual Studio - Fatal编程技术网

C 从改变指针地址的函数返回,地址保持不变

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

我编写了一个更复杂的程序,但我已将问题缩小到以下方面: 为什么这个程序打印的是垃圾而不是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*) 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;        
}