Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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_Variables_Pointers_Memory Address - Fatal编程技术网

函数中使用的内存何时可用??(C编程)

函数中使用的内存何时可用??(C编程),c,variables,pointers,memory-address,C,Variables,Pointers,Memory Address,下面是代码 守则: #包括 int*num(无效); 内部主(空) { int*num2; num2=num(); printf(“%d\n”,*num2); 返回0; } int*num(无效) { int num=20; return# } 问题是: 我们知道,函数num是其函数num()的本地函数,因此在这段代码中,我尝试将函数中变量num的地址返回给调用它的函数,即main() 之后,我只需使用解引用操作符提取特定num变量的值,并在main()函数中打印出来 有一件事我很困惑

下面是代码

守则:

#包括
int*num(无效);
内部主(空)
{
int*num2;
num2=num();
printf(“%d\n”,*num2);
返回0;
}
int*num(无效)
{
int num=20;
return#
}
问题是:

  • 我们知道,函数
    num
    是其函数
    num()
    的本地函数,因此在这段代码中,我尝试将函数中变量
    num
    的地址返回给调用它的函数,即
    main()

  • 之后,我只需使用解引用操作符提取特定
    num
    变量的值,并在
    main()
    函数中打印出来

  • 有一件事我很困惑。我记得我读过一本关于javascript的书,书中提到变量生命周期在函数中,这意味着在函数完成其指令并将控件传递回调用它的函数后,函数中每个变量的值都将被清除(垃圾收集器)。但为什么在这段代码中函数仍然可以指向该特定内存地址的值


  • 返回指向局部变量的指针是不正确的。变量
    num
    在该函数返回且该内存地址可供C运行时用于另一个值时释放。返回的指针现在无效,因为它指向未分配的内存区域,如果使用,将调用未定义的行为。未定义的行为意味着它可能做或不做你想做的事情。在某些情况下,程序会崩溃,在另一种情况下,它可能会工作。它之所以在这种情况下工作,是因为该部分内存仍将保留值
    20
    。取消分配后,C运行时不会用0填充该部分内存。

    可以看到变量值的原因在于堆栈的工作方式。当您输入函数
    num
    时,一个指针(堆栈指针)将被移动,以便为函数的本地存储添加空间。退出函数时,堆栈指针将向后移动,这意味着下一个函数调用将覆盖上一个函数调用中使用的堆栈存储。但是,在被覆盖之前,该值存在于某种模糊状态中。它实际上仍然存在于内存中,但随时可能被覆盖。实际值的存在可能存在,也可能不存在。这就是为什么像上面那样做被称为未定义行为的原因


    基本上。。。不要这样做。

    只是在@Goz解释得很好的基础上增加了一些内容。请尝试以下代码:

    #include <stdio.h>
    
    int * num(void);
    
    int fib(int n)
    {
        if( 0 == n || 1 == n )
            return n;
    
        return fib(n-1) + fib(n-2);
    }
    
    int main(void)
    {
        int * num2;
        num2 =num();
        (void)fib(7);
        printf("%d\n" , *num2);
    
        return 0;
    }
    
    
    int * num(void)
    {
        int num = 20;
    
        return &num;
    }
    
    #包括
    int*num(无效);
    整数fib(整数n)
    {
    如果(0==n | | 1==n)
    返回n;
    返回fib(n-1)+fib(n-2);
    }
    内部主(空)
    {
    int*num2;
    num2=num();
    (无效)fib(7);
    printf(“%d\n”,*num2);
    返回0;
    }
    int*num(无效)
    {
    int num=20;
    return&num;
    }
    
    很有可能您不会得到“20”作为输出(也有可能程序终止)
    此外,在编译时,编译器会警告您“警告:函数返回局部变量的地址”:)

    main中的代码仍然可以指向该内存地址的原因是,与JavaScript不同,C中没有垃圾收集器。这一点与下面的4个答案相矛盾。我不知道你在看哪一个答案,但你在考虑动态范围吗?动态范围从堆栈中清除对象,这是与垃圾收集不同的概念。
    #include <stdio.h>
    
    int * num(void);
    
    int fib(int n)
    {
        if( 0 == n || 1 == n )
            return n;
    
        return fib(n-1) + fib(n-2);
    }
    
    int main(void)
    {
        int * num2;
        num2 =num();
        (void)fib(7);
        printf("%d\n" , *num2);
    
        return 0;
    }
    
    
    int * num(void)
    {
        int num = 20;
    
        return &num;
    }