c pointers and memory allocation
Code:
char *create_string(int str_size)
{
char* string = malloc(sizeof(char)*str_size );
return string;
}
void my_function(void)
{
char* my_str = create_string(255);
}Does my_function() automatically release the memory block pointed to by my_str when the function returns(like it would for a local variable), or do I have to manually free() it?
Memory management in C is 100% manual and painful.
Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
If you malloc it, you're responsible for calling free on it. I don't see how that's painful in any way whatsoever, at all.
So all those memory management schemes like retain counting and garbage collection are all for nothing? Of course it's painful
AnotherJake Wrote:I don't see how that's painful in any way whatsoever, at all.





Seriously, you guys have a problem managing your memory? To the point of it being *painful*?
FreakSoftware Wrote:So all those memory management schemes like retain counting and garbage collection are all for nothing?
No, I never even meant to hint at anything remotely like that. I just don't see how mallocing some memory when you need it and then freeing it later when you don't is somehow even sort of painful. If that were the case, then WTF does anyone use C in the first place?!
Thanks.
One more question if I may, is this code correct for tokenizing a c string? It appears to work, but I've had issues with similar code which also "appeared" to work fine, until it didn't.
the string is the sting to parse, which gets dismembered in the process, token_list[] the a list of pointers to each token, and max_tokens is the size of token_list[]
One more question if I may, is this code correct for tokenizing a c string? It appears to work, but I've had issues with similar code which also "appeared" to work fine, until it didn't.
the string is the sting to parse, which gets dismembered in the process, token_list[] the a list of pointers to each token, and max_tokens is the size of token_list[]
Code:
int tokenize(char* string,char *token_list[], int max_tokens)
{
int cnt = 1;
printf("string: %s\n", string);
token_list[0] = strtok( string, " ");
if (token_list[0] == NULL )
{
return 0;
}
printf("%i: %s\n", cnt, token_list[0]);
while(1)
{
if (cnt >= max_tokens)
{
return cnt;
}
token_list[cnt] = strtok(NULL, " ");
if (token_list[cnt] == NULL)
{
printf("tokenization complete!\n");
return cnt;
}
printf("%i: %s\n", cnt, token_list[cnt]);
cnt++;
}
}
Agree with AnotherJake. Malloc+Free are shit-easy rules to remember - I had to read the "Memory Management Programming Guide for Cocoa" a few times and refer back to it several times more before I knew what the hell was going on there.
AnotherJake Wrote:No, I never even meant to hint at anything remotely like that. I just don't see how mallocing some memory when you need it and then freeing it later when you don't is somehow even sort of painful.
That's fine as long as that object (in the loosest sense) has a well-defined lifetime. Now allocate some memory, read into it from a file, take no-copy substrings of it ('cos you sure wouldn't want to have multiple unnecessary copies of all that text), scatter those substrings to the wind through your program, and figure out when you can free the original block (and heck, reference counting solves *that* problem; there are far worse usage patterns that only GC deals with).
Quote:If that were the case, then WTF does anyone use C in the first place?!
In general, that's a very good question. Unfortunately, there is a degree of interoperability and a degree of performance that only C offers, still.
OneSadCookie Wrote:That's fine as long as that object (in the loosest sense) has a well-defined lifetime. Now allocate some memory, read into it from a file, take no-copy substrings of it ('cos you sure wouldn't want to have multiple unnecessary copies of all that text), scatter those substrings to the wind through your program, and figure out when you can free the original block.
In other words, make a complete mess for yourself and then see if you can figure out how to work within it without bothering to clean it up?
Garbage collection doesn't mean you can completely stop thinking about object ownership and lifecycle. It just pushes the problem further down so that if you're lazy about it, you'll have a much harder time finding and fixing memory problems when they do inevitably show up.
In other words, make a reasonable decision (that it's unacceptable to copy or duplicate that amount of data in order to build the data structure you require), and get left hanging.
in 99% of cases, GC *does* allow you to forget about object ownership and lifecycle. Yes, the remaining 1% of cases cause leaks, which are just as hard to debug as in a manually managed paradigm, but they don't cause crashes.
in 99% of cases, GC *does* allow you to forget about object ownership and lifecycle. Yes, the remaining 1% of cases cause leaks, which are just as hard to debug as in a manually managed paradigm, but they don't cause crashes.
@ NelsonMandella: Stay out of this. It doesn't concern you. 
Just kidding of course... Glancing at your tokenization function I don't see anything that suggests to me that it wouldn't work. What happens when it fails on you?
I have a small primitive I call "Array" for this. If something needs to be deleted but other object(s) are using it, it gets queued in Array. Array gets checked periodically and there is a small reference count in the object being queued for deletion. When the count hits zero, Array deletes the object. It's that simple, and I didn't have to switch languages to get the functionality. Array also allows for a destructor to be called back, of course.
Again, don't get me wrong, as I am not suggesting in any way that garbage collection or other kinds of memory management schemes aren't desirable. The "painful" thing though? No, I don't agree with that in any general sense at all. Are there times when a better memory management scheme would be called for? Yes, most definitely. I haven't personally had a need for anything I can't do with my Array primitive though. Obviously, YMMV depending upon what you're doing.

Just kidding of course... Glancing at your tokenization function I don't see anything that suggests to me that it wouldn't work. What happens when it fails on you?
OneSadCookie Wrote:That's fine as long as that object (in the loosest sense) has a well-defined lifetime. Now allocate some memory, read into it from a file, take no-copy substrings of it ('cos you sure wouldn't want to have multiple unnecessary copies of all that text), scatter those substrings to the wind through your program, and figure out when you can free the original block (and heck, reference counting solves *that* problem; there are far worse usage patterns that only GC deals with).
I have a small primitive I call "Array" for this. If something needs to be deleted but other object(s) are using it, it gets queued in Array. Array gets checked periodically and there is a small reference count in the object being queued for deletion. When the count hits zero, Array deletes the object. It's that simple, and I didn't have to switch languages to get the functionality. Array also allows for a destructor to be called back, of course.
Again, don't get me wrong, as I am not suggesting in any way that garbage collection or other kinds of memory management schemes aren't desirable. The "painful" thing though? No, I don't agree with that in any general sense at all. Are there times when a better memory management scheme would be called for? Yes, most definitely. I haven't personally had a need for anything I can't do with my Array primitive though. Obviously, YMMV depending upon what you're doing.
Like I said, reference counting solves *that* particular problem.
Any time I've built any remotely large system in a language with manual memory management I've had at least one kind of object where the lifetimes were essentially unmanageable, and had to make a significant workaround (implementing refcounting in C, implementing a pool allocator, etc.).
Most times I've built any remotely large system in a language with garbage collection, I've had no problems at all.
Why *would* you use C?
Any time I've built any remotely large system in a language with manual memory management I've had at least one kind of object where the lifetimes were essentially unmanageable, and had to make a significant workaround (implementing refcounting in C, implementing a pool allocator, etc.).
Most times I've built any remotely large system in a language with garbage collection, I've had no problems at all.
Why *would* you use C?
Hehe... Looks like we lost a good chunk of this thread! I noticed over at iDevApps that some moderator actions I took yesterday got rolled back too, so I assume this has something to do with the forum management from yesterday.
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Objective-C Class allocation crash | MrMegabytes | 2 | 2,888 |
Jan 12, 2009 02:28 PM Last Post: DoG |
|
| C++ pointers (multiple uses inside a class) problems :( | wyrmmage | 14 | 5,359 |
Jun 2, 2007 10:08 AM Last Post: akb825 |
|
| trouble with structure pointers | ferum | 2 | 2,585 |
Mar 24, 2006 05:57 PM Last Post: ferum |
|
| Problems With Arrays of Pointers | Nick | 8 | 3,535 |
Sep 27, 2005 04:53 PM Last Post: Zekaric |
|
| pointers to structs | Atomical | 13 | 4,307 |
Jul 17, 2005 10:55 AM Last Post: Steven |
|

