2

So I started playing around with C and having a lot of fun thus far.

There are however a couple of things I can not wrap my head around.

I know that this will end up on the stack

int i = 0;

I know this will reserve space for an integer on the heap and return the adress

int *i = malloc(sizeof(int));

However. If i do this

int i_one = 1, i_two = 2;
int *arr = calloc(2, sizeof(int));
arr[0] = i_one;
arr[1] = i_two;

i_one and two are stack allocated while arr is on the heap. Does this mean that arr will copy the values of i_one and two on to the heap or will it simply hold 2 references to variables on the stack. Im assuming its a variant of alt one considering (if I'm not misstaken) my stack allocated ints will be freed as soon as I exit this function.

So to summarize, when creating a dynamically allocated array using calloc. Do the entries in the array need to be pointers / heap allocated as well? In my head that would not make sense because then wouldnt i create an array of int pointers instead? And yes I know the size of a pointer is the same as an int so the example is a bit stupid but you get the point.

Thank you

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Johan Fredin
  • 573
  • 2
  • 5
  • 12
  • int and pointer isn't the same size (that's depend on the system) :) int is 4 bytes while pointer is word size (4/8 bytes in our life time :) ) – Asaf Itach Apr 29 '21 at 08:47
  • Really? I thought a pointer was always the same size in bytes as an integer be that 4 or 8 bytes depending on os. – Johan Fredin Apr 29 '21 at 12:09

3 Answers3

3

The assignment operator is designed to assign a value stored in one object to another object.

So in these assignment statements

arr[0] = i_one;
arr[1] = i_two;

values stored in the variables i_one and i_two are copied into the memory occupied by the array elements arr[0] and arr[1]. Now if you will change for example the value stored in the variable i_one then the value stored in arr[0] will not be changed.

If you want to store references to objects i_one and i_two in the heap then you should write

int **arr = calloc(2, sizeof(int *));
arr[0] = &i_one;
arr[1] = &i_two;

Now you can change for example the value stored in i_one by means of the array element arr[0] the following way

*arr[0] = 10;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I think in my case it would be easier to store that actual values since I dont need them to be pointers and once created i will not need to modify them (at least not the original values). But that means that when I do arr[0] = i_one; arr[1] = i_two; Then copies of i_one and two live on the heap correct? and once I do free(arr). Then those copies are removed from the heap as well I assume? Unlike the example with an array of pointers. – Johan Fredin Apr 29 '21 at 09:28
  • @JohanFredin If you will free the memory pointed to by the pointer arr then values stored in the dynamically allocated array will not be acceptable. But the values stored in i_one and i_two will be alive. – Vlad from Moscow Apr 29 '21 at 09:35
2

You say that with

int *i = malloc(sizeof(int));

this will end up on the heap

Actually, things aren't quite as simple as that...

If the variable i is a local variable inside a function, then the space for the variable itself will be located in "automatic storage", i.e. the stack. But the pointer returned by malloc will point to the heap.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • and would be access-able from every point in the program so if you will return `i` the heap address will be sent back – Asaf Itach Apr 29 '21 at 08:44
  • @AsafItach Yes, the value of `i` will be copied and returned, and that value is the location of (the first byte of) the heap-allocated memory. And the life-time of heap-allocated memory is until the pointer returned by `malloc` is passed to `free`. – Some programmer dude Apr 29 '21 at 08:49
  • correct! i presume you familiar with this post.. (even tho i'm always use free each time i malloc things) [link](https://stackoverflow.com/questions/654754/what-really-happens-when-you-dont-free-after-malloc) – Asaf Itach Apr 29 '21 at 08:51
  • @Someprogrammerdude Thank you for the correction, I was oversimplifying it. Yes, malloc will create space for an int on the heap and i will hold the address to it and I would have to keep track of it and free it when no longer needed. – Johan Fredin Apr 29 '21 at 09:23
1

I checked the memory map by printing all relevant types or symbols to my knowledge (originally i used static libraries, dynamic loading, and run-time loading but it can be a bit confusing).

I also crated two "heap variables" and print their address and the local pointer which contain their address

->->-> so you can see the local pointer is in the stack but their actual address is at the beginning of the heap. and that's why you can use this allocated variables outside the stack frame - your local pointer get deleted but the address is stayed at the heap.

this is my program output:

 ------------------COMMAND-LINE------------------
 |*envp--------------------->           140737488347777|
 |*argv--------------------->           140737488347751|
 
 |envp--------------------->            140737488346896|
 |argv--------------------->            140737488346864|
 
 
 ------------------STACK------------------
 |str1--------------------->            140737488346090|
 |alloc_second address----->            140737488346048|
 |alloc_first address------>            140737488346040|
 |const_local_second ------>            140737488346032|
 |const_local_first-------->            140737488346024|
 |argc--------------------->            140737488346012|
 ------------------FUNC-STACK-FRAME------------------
 |fun_var_const------------>            140737488345956|
 |fun_var_second----------->            140737488345952|
 |fun_var------------------>            140737488345948|
 
 
 ------------------HEAP------------------
 
 ------------------------MMS---------------------------------------
 |strlen(library func)----->            140737353401952|
 ----------------------------------------------------------------
 
 |alloc_second------------->                4215488|
 |alloc_first-------------->                4215456|
 
 
 ------------------BSS------------------
 |global_const = 0 -------->                4210812|
 |global_int_first--------->                4210808|
 |global_double_first------>                4210800|
 |static_int_first--------->                4210796|
 |global_int_const--------->                4202504|
 
 |------------------DATA------------------
 |static_int_second-------->                4210784|
 |global_double_second----->                4210776|
 ------------------DATA - READ ONLY------------------
 |const_static_int_second-->                4204408|
 |const_static_int_first--->                4204412|
 |string literal----------->                4202700|
 
 
 ------------------TEXT------------------
 |extern function --------->                4200215|
 |function (define after)-->                4200181|
 |main -------------------->                4199038|
 |static function --------->                4198870|
 
 -----------------------BOTTOM LINE------------------
 
Asaf Itach
  • 300
  • 6
  • 13