1. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Mar 2013
Posts
12
Rep Power
0

#### [HELP] Noob question about memory allocation with variables.

Hi,

I have some confusion understanding memory allocations. Please correct me if I am wrong:

Code:
```    int c;                             //(4 bytes).Allocates memory in stack
printf("%u %u\n", c, &c);
short *d;                          //Pointer(4 bytes). Allocates memory in Read-Only data Segment.
printf("%u %u\n", d, &d);
c=5;                                //Allocate the value at the address
d=6;                                //Change the pointer to repoint the address to the location of "6"?
printf("%u %u\n", c, &c);
printf("%u %u\n", d, &d);

/*
Result
42  2686744                        //c=undeclared so is random number. Address of c is 2686744
4996328 268740                     //Not sure what is the first value? The actual address of the var d? Address of Pointer d is 268740
5   2686744                        //c is assigned the value of 5 at address 2686744
6   2686740                        //Pointer d is now assigned the value of 6? Its a pointer as it is 4 bytes instead of 2 for short type.
Issn't the pointer is suppose to hold the address location? How come it is now changed to the assigned value?
*/```
So if d is a pointer, does this means that if I input "d=6", I am ripping off the address information of the actual var d to a value of "6" in the pointer? So now pointer d holds a value of 6 and no longer hold any address data? If pointer d is overwritten with a value data, does this means that the actual var d is still lurking somewhere in the memory at 4996328? Sorry if it looks confusing to you, I hope you can understand,

Thanks!!
2. If you do an assignment to d, d = anything valid, you change the address which d points to. If you do something arbitrary like "d = 6", it is likely d now points to garbage. In your example, d is a pointer to a short integer, and you should not treat it as an actual integer.

suppose you do
c = 5; //c is an int
d = &c; //d points to c

Once you've done this, d points to an integer, c, which is equal to 5. If you assign something different to d afterwards it doesn't change c, it just makes d point to something else.
3. Let's start by looking at compiler warnings.
Code:
```\$ cat bar.c
#include <stdio.h>
#include <stdlib.h>

int main ( ) {
int c;                             //(4 bytes).Allocates memory in stack
printf("%u %u\n", c, &c);
short *d;                          //Pointer(4 bytes). Allocates memory in Read-Only data Segment.
printf("%u %u\n", d, &d);
c=5;                                //Allocate the value at the address
d=6;                                //Change the pointer to repoint the address to the location of "6"?
printf("%u %u\n", c, &c);
printf("%u %u\n", d, &d);
return 0;
}
\$ gcc -Wall bar.c
bar.c: In function ‘main’:
bar.c:6:5: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 3 has type ‘int *’ [-Wformat]
bar.c:8:5: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘short int *’ [-Wformat]
bar.c:8:5: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 3 has type ‘short int **’ [-Wformat]
bar.c:10:6: warning: assignment makes pointer from integer without a cast [enabled by default]
bar.c:11:5: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 3 has type ‘int *’ [-Wformat]
bar.c:12:5: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘short int *’ [-Wformat]
bar.c:12:5: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 3 has type ‘short int **’ [-Wformat]```
> short *d; //Pointer(4 bytes). Allocates memory in Read-Only data Segment.
No, the variable d is on the stack, probably quite close to c (see the addresses it prints in your results)

> d=6; //Change the pointer to repoint the address to the location of "6"?
It isn't the location of 6, '6' or "6", the address IS 6.
You would have been better doing
d = 2686744; // see addresses below.
or better still
d = &c; // but you would need to make the short/int consistent

> 42 2686744 //c=undeclared so is random number. Address of c is 2686744
So far, so good.

> 4996328 268740 //Not sure what is the first value? The actual address of the var d? Address of Pointer d is 268740
First value is the same kind of random garbage which is in c.

> 5 2686744 //c is assigned the value of 5 at address 2686744
Yes.

> 6 2686740 //Pointer d is now assigned the value of 6?
Also yes.

However, 6 is not going to be a valid address, so fortunately for you at the moment you don't try to use *d.

> Its a pointer as it is 4 bytes instead of 2 for short type.
You shouldn't be over reliant on the number of bytes each data type occupies on any given machine.
Pointers on my machine are 8 bytes.
Here is your code with fixes
Code:
```\$ cat bar.c
#include <stdio.h>
#include <stdlib.h>

int main ( ) {
unsigned int c;
printf("%u %p\n", c, &c);
unsigned int *d;
printf("%p %p\n", d, &d);
c=5;
d=&c;
printf("%u %p\n", c, &c);
printf("%u %p %p\n", *d, d, &d);
return 0;
}
\$ gcc -Wall bar.c
\$ ./a.out
0 0x7fff6d9d8e1c
0x7fff6d9d8f00 0x7fff6d9d8e10
5 0x7fff6d9d8e1c
5 0x7fff6d9d8e1c 0x7fff6d9d8e10```
Make careful note of the last printf.
4. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Mar 2013
Posts
12
Rep Power
0
Thanks for the reply! I understand better now. Let me show you another example. I understand the bytes changes with computers but lets keep it this way so I can differentiate for now. Correct me if I am wrong:

Code:
```    char *str;                              //Creates a char pointer in the stack(4bytes).
printf("%u %u\n", str, &str);
char str2[10]={0};                      //Creates a 10 char array in the stack(10bytes) and set all to 0.
printf("%u %u\n", str2, &str2);
char *str3=malloc(sizeof(char)*8);      //Creates a char pointer in the stack(4 bytes) and allocate 8bytes to the heap?
printf("%u %u\n", str3, &str3);

printf("\n");

str="Hello";                            //Repoint str to the address of newly created string "Hello\0" in the memory. stack, heap?
str2[0]='B';                            //Assign chars at the address each element of str2.
str2[1]='l';
str2[2]='a';
str2[3]='c';
str2[4]='k';
str2[5]='\0';
str3="Green";                            //Repoint str3 to the address of newly created string "Green\0" in the heap?

printf("%s\n", str);
printf("%s\n", str2);
printf("%s\n", str3);

printf("\n");

printf("%u %u\n", str, &str);
printf("%u %u\n", str2, &str2);
printf("%u %u\n", str3, &str3);

printf("\n");

/*
4201232 2686736                             //Garbage. Address of pointer str
2686726 2686726                             //Being a char array, both are address of the beginning of the char array str2
9708336 2686720                             //Garbage. Address of pointer str3? However there is a 6 bytes different? Shouldn't
it be 4 bytes? Is it because its not in the stack but in the heap so there is a 2 byte in betweem.
Hello                                         If printed &str3+1, it shows 2686724, which means 2686724 and 2686725 are not occupied.
Black
Green

2686726 2686726                             //Being a char array, both are address of the beginning of the char array str2
4227148 2686720                             //Address of string "Green\0". Same problem as above.

/*```
So if you repoint a pointer to some string, where is this memory allocated at? Also how can we know if the malloc function works since it only shows the address of the pointer? Hope you can understand,

Thanks!!
5. > str="Hello"; //Repoint str to the address of newly created string
> str3="Green"; //Repoint str3 to the address of newly created string "Green\0" in the heap?
The actual "strings" are stored in (typically) the code or read-only data sections of the compiled program. The strings exist throughout the life of the program in the same way that say "%s\n" string parameter to printf exists through the life of the program.

[quote]
9708336 2686720 //Garbage. Address of pointer str3? However there is a 6 bytes different? Shouldn't
it be 4 bytes? Is it because its not in the stack but in the heap so there is a 2 byte in betweem.
Hello If printed &str3+1, it shows 2686724, which means 2686724 and 2686725 are not occupied.
[/quote
You have three things on the stack
- a 4 byte pointer
- a 10 byte array
- a 4 byte pointer
However, in case you haven't noticed yet, all pointers are stored on 4-byte boundaries (on your machine). Your 10-byte array isn't a multiple of 4, so this creates a small hole in memory which is unused.

Try making str2 11 and 12 bytes respectively, and observe.
6. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Mar 2013
Posts
12
Rep Power
0

So all these items, like the string "green", "black", printf, "\n" are actually the read-only data sections of the compiled program?

For example:
char *str3=malloc(sizeof(char)*8);

str3[0]='K';
str3[1]='I';
str3[2]='N';
str3[3]='G';
str3[4]='\0';

printf("%s\n", str3);
printf("%u %u\n", str3, &str3);

Result:
KING
4201406 2686732 --- Points to 4201406. Pointer address is 2686732.

So if I use malloc, it means memory 4201406-4201414 is reserved for my usage?

However, by using malloc, does it reserve a 8byte memory at that portion of the memory? Which is also the heap and not the stack?

char *str3=malloc(sizeof(char)*8); -- reserve memory in heap
char str[8]; -- reserve memory in stack

Thanks!!
7. > So if I use malloc, it means memory 4201406-4201414 is reserved for my usage?
Yes.

> However, by using malloc, does it reserve a 8byte memory at that portion of the
> memory? Which is also the heap and not the stack?
yes, malloc typically gets it's memory from the heap(*).

> char *str3=malloc(sizeof(char)*8); -- reserve memory in heap
The variable str3 itself is on the stack.
The 8 bytes it points to is on the heap.

> char str[8]; -- reserve memory in stack
Or global memory, depending on the context in which you declare it.

(*) Note that the C standard doesn't actually mention things like 'stack' or 'heap'. It only requires that the implementation behaves in a certain way. Heaps and stacks are common ways of achieving that behaviour.
8. No Profile Picture
Registered User
Devshed Newbie (0 - 499 posts)

Join Date
Mar 2013
Posts
12
Rep Power
0
Originally Posted by salem
> So if I use malloc, it means memory 4201406-4201414 is reserved for my usage?
Yes.

> However, by using malloc, does it reserve a 8byte memory at that portion of the
> memory? Which is also the heap and not the stack?
yes, malloc typically gets it's memory from the heap(*).

> char *str3=malloc(sizeof(char)*8); -- reserve memory in heap
The variable str3 itself is on the stack.
The 8 bytes it points to is on the heap.

> char str[8]; -- reserve memory in stack
Or global memory, depending on the context in which you declare it.

(*) Note that the C standard doesn't actually mention things like 'stack' or 'heap'. It only requires that the implementation behaves in a certain way. Heaps and stacks are common ways of achieving that behaviour.
Thanks alot. It clears up my doubts so far!