Thread: Dynamic mem allocation, how to get it right?

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    Quote Originally Posted by Subsonics View Post
    Hmm, ok. But at a first look it seems that explicitly adding one to whatever address the pointer contains should do what I want since what Iīm pointing to is a byte array.
    But the compiler does not know that!
    C is statically typed - the compiler knows only what type of information you have by looking at the type at compile time. If you cast it to void*, then the compiler has lost all track of the type.

    Not exactly sure what you are saying here. Do you mean that the allocated memory essentially is a pointer to the first address of an array. If so how should I declare it.
    UInt8* is not the same as Uint8**.
    The first is a pointer that points to one or more Uint8, and the second is a pointer that points to one or more Uint8*!

    Yes I know, but I said 'for now' meaning until I have found a solution.
    That is not good enough!
    This particular warning is more of an error, since it will 99% likely crash your program.
    You must solve it right away before venturing further with the code.

    Now, if you get that warning again, post the relevant code and we can point out what went wrong. A typical example that this warning says is this:
    Code:
    int* p = 0;
    int x = p; // Warning: assignment makes integer from pointer without cast
    p = x; // Warning: assignment makes pointer from integer without cast
    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.

  2. #17
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by Elysia View Post
    Now, if you get that warning again, post the relevant code and we can point out what went wrong.
    Ok, the following gives me the warning. I guess I could do it in another way based on what have been presented earlier, but itīs interesting to see why things goes wrong.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
    	typedef unsigned char UInt8;
    	int i;
    	int size = 10;
    	UInt8 *temp = malloc(size);
    	UInt8 container[size];
    	UInt8 *pt;
    	
    	pt = &temp; // <-- This raises the warning
    	
    	for(i = 0; i < size; i++) {
    		container[i] = *pt;
    		pt++;
    	}
    	
    	free(&temp);	
    	return 0;
    }
    Just to clarify this generates: warning: assignment from incompatible pointer type

    I originally attempted to get past this by using a void pointer, but that just turned into a new problem that showed up in the for loop.
    Last edited by Subsonics; 02-08-2009 at 05:16 AM.

  3. #18
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,401
    pt is of type pointer to UInt8. temp is also of type pointer to UInt8. As such, it does not make sense to assign the address of temp, which is of type pointer to pointer to UInt8, to pt. It might make sense to assign temp to pt.

    Likewise, temp points to the first element of the array allocated by malloc(). It makes sense to write free(temp), but it does not make sense to write free(&temp), since temp itself is not dynamically allocated.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #19
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,786
    pt = &temp; // <-- This raises the warning

    you should get rid of & in this line
    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

  5. #20
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Ahh, yes. It makes sence now. I just added the address of operator out of habit without thinking about the * in the declaration. Now this raises the question if *pt is needed at all in this example, or if I just as well could make the assignments from, and increment temp directly in the for loop?

    I got rid of & in free() as well, I first got a warning about it not being there possibly from making the assignement from &temp to begin with. Anyway it works now! Perfect thank you all.

  6. #21
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,786
    I got rid of & in free() as well
    you shuld leave the free

    and for freeing original pointer - you need pt that will be incremented
    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

  7. #22
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,401
    Quote Originally Posted by Subsonics
    Now this raises the question if *pt is needed at all in this example, or if I just as well could make the assignments from, and increment temp directly in the for loop?
    If you change temp, you would have no way to free the memory from malloc(), unless you keep track of the change and "undo" it. I find it easier to just use another pointer like you did with pt, or to use an index, e.g.,
    Code:
    container[i] = temp[i];
    Quote Originally Posted by vart
    you shuld leave the free
    Subsonics is talking about removing the address of operator from the argument to free(), not about removing the call to free().
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #23
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by vart View Post
    you shuld leave the free

    and for freeing original pointer - you need pt that will be incremented
    Ok, what I meant was the address of operator in the argument field of free().

    BTW I just tried using temp directly in the for loop but got this error while freeing it.
    Code:
    	
    	for(i = 0; i < size; i++) {
    		container[i] = *temp;
    		temp++;
    	}
    test(6364) malloc: *** error for object 0x10012a: Non-aligned pointer being freed
    *** set a breakpoint in malloc_error_break to debug

    Adding

    temp = NULL;

    before freeing it got rid of the error but Iīm not sure if it does what I want since I donīt inspect the content of container[] in this example.

  9. #24
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,786
    temp = NULL;

    before freeing it got rid of the error but Iīm not sure if it does what I want since I donīt inspect the content of container[] in this example.
    of course it does not

    as I said - you should leve 2 pointers - one is incremented - the other should store the address returned by malloc and should be passed to free
    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

  10. #25
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by laserlight View Post
    If you change temp, you would have no way to free the memory from malloc(), unless you keep track of the change and "undo" it. I find it easier to just use another pointer like you did with pt, or to use an index, e.g.,
    Code:
    container[i] = temp[i];
    Yes using an index makes what is going on pretty clear. I didnīt know that was possible before I saw it used in this thread. Thanks

  11. #26
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by vart View Post
    of course it does not
    Well what can I say, things become simple once you understand them. ;-)

  12. #27
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    Quote Originally Posted by Subsonics View Post
    Ok, the following gives me the warning. I guess I could do it in another way based on what have been presented earlier, but itīs interesting to see why things goes wrong.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, char *argv[])
    {
    	typedef unsigned char UInt8;
    	int i;
    	int size = 10;
    	UInt8 *temp = malloc(size);
    	UInt8 container[size];
    	UInt8 *pt;
    	
    	pt = &temp; // <-- This raises the warning
    	
    	for(i = 0; i < size; i++) {
    		container[i] = *pt;
    		pt++;
    	}
    	
    	free(&temp);	
    	return 0;
    }
    Just to clarify this generates: warning: assignment from incompatible pointer type

    I originally attempted to get past this by using a void pointer, but that just turned into a new problem that showed up in the for loop.
    You assign the address of a pointer to another pointer. Obviously, taking the address of a pointer will give you a pointer to that pointer. Which screws up everything afterwards, since dereferencing that pointer, pt, will give you the address of the pointer it points to, but the compiler will think that it is Uint8, which it is not!
    And as for free, you must free what you malloc. Free expects the address that you originally got from malloc. So if you pass the address of the pointer that contains the address you got from malloc, what happens then? Nothing good at least.

    Quote Originally Posted by Subsonics View Post
    Ok, what I meant was the address of operator in the argument field of free().

    BTW I just tried using temp directly in the for loop but got this error while freeing it.
    Code:
    	
    	for(i = 0; i < size; i++) {
    		container[i] = *temp;
    		temp++;
    	}
    test(6364) malloc: *** error for object 0x10012a: Non-aligned pointer being freed
    *** set a breakpoint in malloc_error_break to debug

    Adding

    temp = NULL;

    before freeing it got rid of the error but Iīm not sure if it does what I want since I donīt inspect the content of container[] in this example.
    Again, free expects the address that was returned from malloc. If you increment the address, then you don't have the original address returned by malloc anymore! And what happens then? Nothing good at least.
    And so you set it to NULL before calling free. That is going to help... how, exactly? Free needs the original address returned by malloc to identify what allocation it should free! And if pass NULL to free, how is it supposed to know what to free?
    Free actually ignores a NULL pointer passed in and returns directly, which is why it works. But is it right? Hardly. You just created a memory leak. Why do you think it is a solution?
    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.

  13. #28
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by Elysia View Post
    And so you set it to NULL before calling free. That is going to help... how, exactly? Free needs the original address returned by malloc to identify what allocation it should free! And if pass NULL to free, how is it supposed to know what to free?
    Free actually ignores a NULL pointer passed in and returns directly, which is why it works. But is it right? Hardly. You just created a memory leak. Why do you think it is a solution?
    Actually, that make perfect sence. I made an attempt to use temp directly in the for loop simply to see for myself what would happen. I have one question about free() though, incrementing the address of the pointer I originaly allocated memory for means trouble, but where does the computer store information about the size of the allocated memory?

  14. #29
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,653
    It's implementation-defined. But usually, it stores it right before the allocated memory itself. Sometimes even after the allocated memory.
    This is the C runtime we're talking about. The OS stores its own information in memory, too, of course. And it, too, need some sort of handle to know what allocation to free. But the C runtime takes care of that.
    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.

  15. #30
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Ok I see, is it possible to get the size of allocated memory somehow? I guess sizeof() wont work.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dynamic allocation from 1 instead of zero
    By cfdprogrammer in forum C Programming
    Replies: 27
    Last Post: 04-28-2009, 08:21 AM
  2. pointer to array with dynamic allocation
    By cfdprogrammer in forum C Programming
    Replies: 22
    Last Post: 04-07-2009, 09:56 AM
  3. Dynamic memory allocation.
    By HAssan in forum C Programming
    Replies: 3
    Last Post: 09-07-2006, 05:04 PM
  4. Dynamic allocation (I thought it would crash)
    By Baaaah! in forum C Programming
    Replies: 16
    Last Post: 11-30-2005, 05:10 PM
  5. dynamic mem allocation prgm crash
    By rip1968 in forum C++ Programming
    Replies: 11
    Last Post: 05-10-2002, 05:09 PM