【问题标题】:Where the nested function's body kept?嵌套函数的主体保存在哪里?
【发布时间】:2020-06-08 22:57:19
【问题描述】:

请检查以下代码,

#include <stdio.h>
#include <string.h>

void* make_adder_function(int a)
{

    char str[64] ={};

    sprintf(str,"this function adds %d with input",a);

    void adder(int b) {
        int x = a;
        char ptr[64] = {};
        strcpy(ptr,str);
        printf("%s\n", ptr);
        printf("%d + %d = %d\n", x, b, x+b);
    }

    return adder;
}


int main()
{
    void (*adder_ten)(int);
    void (*adder_twenty)(int);

    adder_ten = make_adder_function(10);
    adder_twenty = make_adder_function(20);

    adder_ten(20);
    adder_twenty(20);

    return 0;
}

在运行代码时,我得到以下输出,

ajith@chat:~/Desktop$ ./a.out 
this function adds 20 with input
20 + 20 = 40
Segmentation fault (core dumped)

它显示function adder() 的范围仅在make_adder_function() 内,我假设这是因为adder() 的函数体保存在make_adder_function() 的堆栈框架中。任何人都可以对此做出解释吗?如何在整个程序中保持嵌套函数的生命周期?

【问题讨论】:

  • 嵌套函数在 C 中是非标准的。
  • C 没有嵌套函数。嵌套函数是 GCC 的一个不可移植的特定于编译器的扩展。请避免此类扩展。
  • 问题不在于函数,问题在于printf("%s\n", str);,其中str 指的是已达到其生命周期的缓冲区。顺便说一句,您使用的局部变量a 也不会导致崩溃。但是,它可以包含一些任意值。
  • 请不要在收到 cmets 和答案后更改您的代码。您的更改使它们毫无用处。
  • Info on how to correctly emulate a closure in C。摘要:这是一个皮塔饼。

标签: c linux function storage-class-specifier data-segment


【解决方案1】:

您的问题(除了非标准扩展)是make_adder_function 函数内的局部变量str 将在make_adder_function 函数结束时结束其生命周期。这发生在您调用 adder 函数之前,然后该函数会尝试使用不存在的 str 变量。

嵌套函数扩展只嵌套函数,它没有closures

【讨论】:

  • 现在我为超出范围的值添加了局部变量
  • @AjithCNarayanan 这不会改变任何东西,当您将stra 复制到adder() 中时,您仍然使用已经过了生命周期的变量。并且请不要进行使现有答案无效的编辑,如果您想显示当前代码,请在标有“编辑:”或类似内容的原始代码下方进行操作。
  • @AjithCNarayanan 您的更改没有帮助,您仍然尝试使用 str 在其生命周期之后。您现在所做的复制是在调用 adder 时完成的,而不是在调用 make_adder_function 时完成的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多