#1
  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. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2009
    Posts
    149
    Rep Power
    36
    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.
  4. #3
  5. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    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.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  6. #4
  7. 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
    
        4227142 2686736                             //Address of string "Hello\0". Address of pointer str
        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!!
  8. #5
  9. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > 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.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Thanks for the reply.

    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!!
  12. #7
  13. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > 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.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  14. #8
  15. 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!

IMN logo majestic logo threadwatch logo seochat tools logo