-1

Please check the following code,

#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;
}

While Running the code I am getting the following output,

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

It shows like the scope of function adder() is only inside the make_adder_function(), I assumes this happens because the function body of adder() is kept in the stack frame of make_adder_function(). Can anybody give an explanation for this? How can I persist a nested function's lifetime throughout the program?

  • 2
    Nested functions are non-standard in C. – Weather Vane Feb 25 '20 at 08:54
  • C doesn't have nested functions. Nested functions is a non-portable compiler-specific extension of GCC. Please avoid such extensions. – Some programmer dude Feb 25 '20 at 08:54
  • 1
    The problem is not the function, the problem is the `printf("%s\n", str);`, where `str` refers to a buffer that has reached its lifetime. The local variable `a`, that you use, also, btw, but it doesn't lead to a crash. It can contain some arbitrary value, however. – Ctx Feb 25 '20 at 08:56
  • Please to not make changes to your code after receiving comments and answers. Your changes make them useless. – Gerhardh Feb 25 '20 at 09:01
  • [Info on how to correctly emulate a closure in C](https://stackoverflow.com/a/345881/3386109). Summary: it's a pita. – user3386109 Feb 25 '20 at 09:07
  • @user3386109 making a closure in C is trivial -- provided that you don't want to pass it as an argument to a function which expect a simple function pointer as argument. –  Feb 25 '20 at 11:50

1 Answers1

2

Your problem (the non-standard extension aside) is that the local variable str inside the make_adder_function function will have ended its life-time when the make_adder_function function ends. And this happens before you call the adder function, which then tries to use the non-existing str variable.

The nested-function extension only nests functions, it doesn't have closures.

As a simple workaround you could make str a static variable. Its life-time would then be for the full runtime of the program. The problem then is that there's only one variable, which will be shared between all calls to the make_adder_function function.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • now I added local variables for out of scope values – Ajith C Narayanan Feb 25 '20 at 08:59
  • 2
    @AjithCNarayanan That doesn't change anything, you still use variables, that are past their lifetime, when you copy `str` and `a` inside `adder()`. And please do not make edits that invalidate existing answers, if you want to show current code, do it _below_ the original code marked with "Edit:" or similar. – Ctx Feb 25 '20 at 09:03
  • @AjithCNarayanan Your change doesn't help, you still attempt to use `str` after its life-time. The copying you now do is done when `adder` is called, not when `make_adder_function` is called. – Some programmer dude Feb 25 '20 at 09:03