Thread: Dynamic memory allocation problem

  1. #1
    Registered User
    Join Date
    Sep 2013
    Posts
    18

    Dynamic memory allocation problem

    I am now entering the part of memory management.

    As learning from some resources, realloc copies the content pointed by a declared pointer, frees its memory and then allocates a new memory space as well as pasting its previous value.

    The first sample code uses only realloc to dynamically increase the size and input some value.
    It works well.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void){
        
        int i = 0, n = 0, x = 0, *p = NULL;
        
        while(scanf("%d", &x) != EOF){
            ++n;
            p = (int *)realloc(p, n * sizeof(int));
            p[n-1] = x;
            for(i=0; i<n; ++i)
            printf("%d, ", p[i]);
            printf("\n");
            
        }
        
        free(p);
        
        system("pause");
        return 0;
        
    }
    In the second code, I tried to allocate the memory space and give value by malloc.
    Then I tried to use realloc to change the size of memory space but keep the previous value.
    However, it fails.

    Where did I do wrong?
    Thanks!!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void){
        
        
        int n;
        char* pc = NULL;
        int i;
    
    
        scanf("%u",&n);
        
        pc = (char*)malloc(sizeof(char)*n);  // borrow memory spaces using malloc
        
        for(i=0;i<n;i++) pc[i]=(char)i*(char)i;
        
        for(i=0;i<n;i++) printf("%d ",pc+i);
        printf("\n");
        for(i=0;i<n;i++) printf("%d ",*(pc++));
        printf("\n");
        
        //free(pc);
        
        n=n+3;
        
        pc = (char*)realloc(pc,sizeof(char)*n); // try to change the memory size but keep the values using realloc
        for(i=0;i<n;i++) printf("%d ",pc+i);
        printf("\n");
        for(i=0;i<n;i++) printf("%d ",*(pc++));
        printf("\n");
    
    
        free(pc);
        
        system("pause");
        return 0;
        
    }

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you ask realloc to return same amount of memory as allocated by malloc. So it has nothing to do.

    You are using your realloc incorrectly - since you do not handle realloc failure

    Code:
    char* p = malloc(...);
    
    char* temp = realloc(p, ...);
    
    if(!temp)
    {
       /* realloc failed - use p  and old size */
    }
    else
    {
       p = temp; /* use new pointer and new memory size */
    }
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Your second example is not working because you change pc!!! You can't change it to another value and then use it in realloc. It needs to point to the original address returned by malloc.


    Casting the return value of the *alloc functions is discouraged in C since it's unecessary. The pros would write your realloc call like so:
    Code:
    p = realloc(p, n * sizeof(*p));
    This way, if the type of p changes, no changes are necessary to this call.


    As learning from some resources, realloc copies the content pointed by a declared pointer, frees its memory and then allocates a new memory space as well as pasting its previous value.
    realloc does not necessarily copy the memory that the input pointer points to. And when it does, it needs to allocate the new space first! I'm not sure what word you were going for when you typed "pasting", but if it was "passing" as in "passes back" then it's not the previous value but the new value that's passed back. It may in fact be equal to the old value if either the realloc made the memory area smaller or there was enough headroom in the current allocation to accomodate the request.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    Registered User
    Join Date
    Sep 2013
    Posts
    18

    ...

    Quote Originally Posted by oogabooga View Post
    Your second example is not working because you change pc!!! You can't change it to another value and then use it in realloc. It needs to point to the original address returned by malloc.
    I am not sure about what you mean change pc. Do you mean change the value, the type or the memory it points to?
    I did change the value of pc after declaring and initiating NULL. I didn't change its type, it's still char*.
    .

    Quote Originally Posted by oogabooga View Post
    Casting the return value of the *alloc functions is discouraged in C since it's unecessary. The pros would write your realloc call like so:
    Code:
    p = realloc(p, n * sizeof(*p));
    I tried to delete the (char*) and put back it alternatively, it sometimes ran through it and sometimes terminated accidentally.
    Due to the inconsistency, I can't really assure what's going on and which one is correct.


    Quote Originally Posted by oogabooga View Post
    This way, if the type of p changes, no changes are necessary to this call.



    realloc does not necessarily copy the memory that the input pointer points to. And when it does, it needs to allocate the new space first! I'm not sure what word you were going for when you typed "pasting", but if it was "passing" as in "passes back" then it's not the previous value but the new value that's passed back. It may in fact be equal to the old value if either the realloc made the memory area smaller or there was enough headroom in the current allocation to accomodate the request.
    The following is the definition I checked from realloc - cppreference.com.
    According to it, realloc copies the value of the old memory block, allocates a new memory block and passes in the value and de-allocates the olde memory block. (I am not sure the order of those actions)
    But I can't get the new memory block with the old values.

    Defined in header <stdlib.h>
    void *realloc( void *ptr, size_t new_size );
    Reallocates the given area of memory. It must be previously allocated by malloc(), calloc() or realloc() and not yet freed with free, otherwise, the results are undefined.
    The reallocation is done by either:
    a)
    expanding or contracting the existing area pointed to by ptr, if possible. The contents of the area remain unchanged up to the lesser of the new and old sizes. If the area is expanded, the contents of the new part of the array are undefined.

    b)
    allocating a new memory block of size new_size bytes, copying memory area with size equal the lesser of the new and the old sizes, and freeing the old block.

    If there is not enough memory, the old memory block is not freed and null-pointer is returned.


    Thanks for all of your reply!!!!! Thanks

  5. #5
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    free(pc) isn't going to work since the program increments pc in the last loop. Also the 3 extra locations realloc'ed to pc are never initialized.

  6. #6
    Registered User
    Join Date
    Sep 2013
    Posts
    18
    Quote Originally Posted by vart View Post
    you ask realloc to return same amount of memory as allocated by malloc. So it has nothing to do.

    You are using your realloc incorrectly - since you do not handle realloc failure
    Thanks!

    I changed the request size of memory in line 26, n=n+3.
    realloc allocates new memory space. Is it necessary to request a different size?

  7. #7
    Registered User
    Join Date
    Sep 2013
    Posts
    18
    Quote Originally Posted by rcgldr View Post
    free(pc) isn't going to work since the program increments pc in the last loop. Also the 3 extra locations realloc'ed to pc are never initialized.
    Thank you!

    I found this mistake and corrected it but still with some problems.

  8. #8
    Registered User
    Join Date
    Sep 2013
    Posts
    18
    Hello

    I checked the output again and found that the memory address pointed to had been changed without expectation.
    I checked by the following code.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <memory.h>
    #include <string.h>
    
    
    int main(void){
        
        
        int n;
        char* pc = NULL;
        int i;
    
    
        scanf("%u",&n);
        
        pc = (char*)malloc(sizeof(char)*n);  // borrow memory spaces using malloc
        
        for(i=0;i<n;i++) *(pc+i) =(char)i*(char)i;
        
        for(i=0;i<n;i++) printf("%d ",pc+i);
        printf("\n");
        for(i=0;i<n;i++) printf("%d ",*(pc++));
        printf("\n");
        
        printf("n=%d ",n);
        printf("%d ",pc);
        printf("%d ",pc);
        printf("%d ",pc);
        
        printf("\n");
        printf("n=%d ",n);
        printf("%d ",pc+1);
        printf("%d ",pc+1);
        printf("%d ",pc+1);
        printf("\n");
        
        //char* check = 
        
        /*
        for(i=0;i<n;i++) printf("i=%d    %d ",i,pc+i);
        printf("\n");
        for(i=0;i<n;i++) printf("%d ",*(pc++));
        printf("\n");
        
        memset(pc,255,sizeof(char)*2);
        
        for(i=0;i<n;i++) printf("%d ",*(pc++));
        printf("\n");
        */
    
    
        //free(pc);
        
        
        system("pause");
        return 0;
        
    }
    The output is as follows.
    I input n=5, assigned the values and printed the address and value as expectation.
    Then I printed again the address but it was shifted.
    What's the problem with this code?

    5
    4072584 4072585 4072586 4072587 4072588
    0 1 4 9 16
    n=5 4072589 4072589 4072589
    n=5 4072590 4072590 4072590
    請按任意鍵繼續 . . .
    Last edited by HolmesChang; 09-06-2013 at 12:40 AM.

  9. #9
    11DE784A SirPrattlepod's Avatar
    Join Date
    Aug 2013
    Posts
    485
    On line 17, what is the value of pc? (4072584 in your example output)
    When execution gets to line 27, what is the value of pc? (4072589 in your example output)

    What is the difference between these two values (i.e. subtract them)?

    What is the value of the memory at 4072590 (using your example)? Is it "valid" to refer to that address (dereference it)?

  10. #10
    Registered User
    Join Date
    Sep 2013
    Posts
    18
    Quote Originally Posted by SirPrattlepod View Post
    On line 17, what is the value of pc? (4072584 in your example output)
    When execution gets to line 27, what is the value of pc? (4072589 in your example output)

    What is the difference between these two values (i.e. subtract them)?

    What is the value of the memory at 4072590 (using your example)? Is it "valid" to refer to that address (dereference it)?
    Thanks for your hint.
    I think I realize the cause of the problem.
    pc++ equals to pc = pc+1, changing the memory address of pc.
    Its a very basic mistake and I neglect it

    Quote Originally Posted by oogabooga View Post
    Your second example is not working because you change pc!!! You can't change it to another value and then use it in realloc. It needs to point to the original address returned by malloc
    You pointed it out at the first time but I didn't realize it.
    Thank you!

  11. #11
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    if you want to print a value of the pointer - you need to use %p since pointer and int could have different size and %d will have undefined result
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  12. #12
    11DE784A SirPrattlepod's Avatar
    Join Date
    Aug 2013
    Posts
    485
    Quote Originally Posted by vart View Post
    if you want to print a value of the pointer - you need to use %p since pointer and int could have different size and %d will have undefined result
    While correct it matters not in this example.

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by vart View Post
    if you want to print a value of the pointer - you need to use %p since pointer and int could have different size and %d will have undefined result
    It's not only if int and pointers have different sizes. They can also have different representation of values even if they are the same size.

    If using %p, it is often considered a good idea to explicitly convert the supplied pointer to (void *).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  14. #14
    Registered User
    Join Date
    Sep 2013
    Posts
    18
    Quote Originally Posted by vart View Post
    if you want to print a value of the pointer - you need to use %p since pointer and int could have different size and %d will have undefined result
    I have tried %p and compared the output with that using %d.
    With %p, address in hex format is returned while decimal format with %d.
    However, it can't match the output using %p as I tried to transform the output address in decimal format to hex format.

    I don't know what's the difference between these two output yet.
    But I will use %p for all the following cases if I would like to monitor the address of a memory space.

    Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. another dynamic memory allocation problem
    By mp252 in forum C++ Programming
    Replies: 8
    Last Post: 06-24-2013, 02:16 PM
  2. Basic dynamic memory allocation problem
    By Crosshash in forum C Programming
    Replies: 11
    Last Post: 03-22-2011, 01:14 PM
  3. Dynamic memory allocation problem
    By linuxlover in forum C Programming
    Replies: 17
    Last Post: 11-25-2010, 01:11 PM
  4. Problem with custom dynamic memory allocation routines
    By BLauritson in forum C++ Programming
    Replies: 12
    Last Post: 03-11-2010, 07:26 AM
  5. dynamic memory allocation problem
    By firyace in forum C Programming
    Replies: 4
    Last Post: 05-23-2007, 09:57 PM