-1

I have some questions about program stack.

I'm trying to give input array, process them and return processed array.(want to save the input array.) And trying to avoid using globals.

English is not mother tongue so please forgive my English..!

int* func(int* input_array, int size)
{
    int arr_local[20] = {  };
    int* arr_alloc = (int*)malloc(sizeof(int)* 3);

    for (int i = 0; i < size; i++)
    {
        arr_local[i] = input_array[i];
    }
    arr_local[3] = 4;

    /*for (int i = 0; i < size; i++)
    {
        arr_alloc[i] = input_array[i];
    }
    arr_alloc[3] = 4;
    free(arr_alloc);*/

//  return arr_alloc;
    return arr_local;

}

int main()
{

    int input_arr[20] = { 0, };
    printf("%d", func(input_arr,10)[3]);

}

1-1. When I return local_arr which is declared as a local variable in my_func, it works normally in debug mode. but I assume that it's not a good way.

1-2. Program stack is determined on compile time, isn't it?

1-3. Is the program stack is immutable during runtime?

1-4. I guessed if program stack is immutable, I could return arr_local.

2-1 When I used malloc to use heap segment. Can I free(arr_alloc) outside the scope from where it allocated? if it's possible. Is it recommend or not?

2-2 I did free(arr_alloc) before return arr_alloc but it works fine. Is it only because arr_alloc heap memory hasn't been overwrited yet?

3-1 What would be a good code to handle array.

trincot
  • 317,000
  • 35
  • 244
  • 286
longlive
  • 15
  • 4

2 Answers2

1

When I return arr_local which is declared as a local variable in func, it works normally in debug mode. but I assume that it's not a good way.

  • return arr_alloc; is returning a pointer to memory that you correctly allocated somewhere else (in the heap through malloc, not on the stack).
  • return arr_local; is invalid because it's returning a pointer to the stack of the function, which becomes invalid when the function returns.

Program stack is determined on compile time, isn't it?

Not really. It depends on different things at both compile and run time. See Change stack size for a C++ application in Linux during compilation with GNU compiler.

Is the program stack is immutable during runtime?

If you mean immutable in size, it usually is not, but it could be depending on the machine and operating system. It could also be mutable in size but limited to a certain maximum size. See man setrlimit. If you mean "immutable" as in "read only", it definitely is not read only.

When I used malloc to use heap segment. Can I free(arr_alloc) outside the scope from where it allocated? if it's possible. Is it recommend or not?

Yes, it's possible and it's usually almost always done like this. malloc()/free() exist exactly for this purpose: managing memory that needs to be passed across different functions. You usually use some function that does malloc() for you, and then free() the memory somewhere else when it isn't needed anymore, see for example the standard C function strdup().

I did free(arr_alloc) before return arr_alloc but it works fine. Is it only because arr_alloc heap memory hasn't been overwrited yet?

Yes, it's most likely because of that. What you did is invalid. You are returning a pointer to freed memory, which cannot be used correctly! Any code dereferencing the pointer in any way will cause undefined behavior. Only free() something after you are done using it.

What would be a good code to handle array.

Depends on the situation. If you want to create dynamically sized arrays, your code is already a good start, but you have some errors here and there. Here's a better version:

int *copy_array(int *input_array, int size)
{
    int *copy = malloc(sizeof(int) * size);

    for (int i = 0; i < size; i++)
        copy[i] = input_array[i];

    return copy;
}

int main()
{
    int arr[20] = {0};

    // ... 

    int *copy = copy_array(arr, 20);

    // ...  use copy ...

    free(copy);
    return 0;
}

You could also do this with memcpy():

int main()
{
    int arr[20] = {0};

    // ...

    int *copy = malloc(20 * sizeof(int));
    memcpy(copy, arr, 20 * sizeof(int));

    // ... use copy ...

    free(copy);
    return 0;
}
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • Thank you so much for answering my ambiguous question with clear answer!! I'll carefully look at it!(And I changed to arr_local!!) – longlive Apr 20 '20 at 02:55
0

1-1. When I return local_arr which is declared as a local variable in my_func, it works normally in debug mode. but I assume that it's not a good way.

Yes.You don't want to return a pointer to an object that no longer exists because it's not legal to dereference it since it doesn't point to a valid object.

1-2. Program stack is determined on compile time, isn't it?

That's not really a well-defined question. The stack only exists at run time. The code to handle it is created at compile time. The size of the various stacks may or may not be known at compile time.

1-3. Is the program stack is immutable during runtime?

No, it changes constantly.

1-4. I guessed if program stack is immutable, I could return arr_local.

I don't know what this means You would be returning arr_local's value, not arr_local itself. And the value is a pointer to an object on the heap. So what does that have to do with the stack?

2-1 When I used malloc to use heap segment. Can I free(arr_alloc) outside the scope where it allocated? if it's possible. Is it recommend or not?

Yes. You should free it whenever you're done with it.

2-2 I did free(arr_alloc) before return arr_alloc but it works fine. Is it only because arr_alloc heap memory hasn't been overwrited yet?

The value is still a value and it's perfectly fine to return it. Just don't de-reference it. That could do anything because it's a pointer to an object that no longer exists.

3-1 What would be a good code to handle array.

When you need an array, call malloc. Return a pointer to it. When done with it, call free.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Read 2-2 again more carefully – rici Apr 20 '20 at 02:40
  • thank you for all the kind answers! for the 1-4.( I guessed if program stack is immutable, I could return arr_local). Since local_arr is a local variable, it would be exist in stack area. So I assumed it has some relationship with stack! – longlive Apr 20 '20 at 02:44
  • @rici Do you think my answer is wrong? It's perfectly free to do `free(arr_alloc); return arr_alloc;`. You are returning a value that is a valid value, it's just not legal to dereference. (Did my clean up resolve your issue?) – David Schwartz Apr 20 '20 at 02:46