Thread: Dynamic Memory Allocation

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    7

    Dynamic Memory Allocation

    Hi,

    Can anyone explain to me why this code doesn't work well?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void teste(int* n)
    {
    	n = (int*) malloc(sizeof(int));
    	*n = 5;
    }
    
    int main()
    {
    	int* n = 0;
    
    	teste(n);
    
    	printf("Teste: %d", *n);
    
    	return 0;
    }
    I would like to alloc memory inside a procedure passing the pointer I declared before in the main. Is there any way to make this thing work like I expect?

  2. #2
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    Your code doesn't modify the initial pointer in main(): either pass the pointer address (int**) or simply declare an integer in main() and pass its address (but it doesn't require a malloc() this way).

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void teste(int** n)
    {
      *n = (int*) malloc(sizeof(int));
      **n = 5;
    }
    
    int main()
    {
      int* n = 0;
      teste(&n);
      printf("Teste: &#37;d", *n);
      return 0;
    }
    Last edited by root4; 05-14-2008 at 01:21 PM.

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    When you pass 'n' to the function, you are passing the address of an int declared in main. Now, when you use malloc, teste's 'n' will be the address to the newly allocated data, which is not the same pointed by the 'n' in main.

    So your printf in main will not print 5, it will print the value that main's 'n' points at.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, what you pass is a copy of the original pointer.
    So there's no way it can actually change the address of the original pointer because you don't have a pointer to that pointer (sounds familiar?).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    7
    Thanks all... It was a little bit confusing, but now I understand why It isn't working like I was expecting.

    Thanks root4, samus250 and Elysia!

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    So your printf in main will not print 5, it will print the value that main's 'n' points at.
    In fact the initial n (in main) is not modified at all and the result is only a SEGV (as *n is deferencing the address 0).

  7. #7
    Registered User TactX's Avatar
    Join Date
    Oct 2005
    Location
    Germany.Stuttgart
    Posts
    65
    Another way would be to simply return an int* from teste(), which would make the function itself rather pointless...

    And besides:
    - casting mallocs return value is pointless since a void* is implicitly converted to other pointer types
    - avoid using sizeof on types, use sizeof on real objects instead. (sizeof *n) in this case
    - free() your memory when done

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by TactX View Post
    - casting mallocs return value is pointless since a void* is implicitly converted to other pointer types
    And to add to that - it's also dangerous because it can mask a very serious error.
    If you don't include the correct header, the compiler won't see the declaration of malloc, and you will get an "implicit" call to the function, which is very, very bad.
    If you cast the return from malloc, you will hide this warning (the compiler won't warn you). Therefore it is very bad to do so in C.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    Quote Originally Posted by root4 View Post
    In fact the initial n (in main) is not modified at all and the result is only a SEGV (as *n is deferencing the address 0).
    Yes I know that it doesn't get modified, that's kind of what I tried to say. But I did forget about the initialization to 0 :-) .

    What would address 0 hold? I guess its something creepy.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Typically operating systems prevent you from dereferencing address 0. So you get an access violation instead. Which typically results in a crash.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    May 2008
    Posts
    7
    Thanks again! Wow! That was a very nice explanation! Very complete also...

    Thanks to all who answered this thread!

  12. #12
    Registered User
    Join Date
    Jan 2008
    Posts
    182
    Quote Originally Posted by Elysia View Post
    And to add to that - it's also dangerous because it can mask a very serious error.
    If you don't include the correct header, the compiler won't see the declaration of malloc, and you will get an "implicit" call to the function, which is very, very bad.
    If you cast the return from malloc, you will hide this warning (the compiler won't warn you). Therefore it is very bad to do so in C.
    ooops, I've always been casting malloc's return.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by samus250 View Post
    ooops, I've always been casting malloc's return.
    Note that if you ever use malloc() in a C++ program, it will require casting, since void pointers are not automatically converted to other pointer types in C++.

    Of course, you should probably use new....

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  2. Replies: 16
    Last Post: 01-01-2008, 04:07 PM
  3. Dynamic memory allocation.
    By HAssan in forum C Programming
    Replies: 3
    Last Post: 09-07-2006, 05:04 PM
  4. Dynamic memory allocation...
    By dicorr in forum C Programming
    Replies: 1
    Last Post: 06-24-2006, 03:59 AM
  5. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM