Question On Malloc And Free.


Uprising

Member
Joined
Mar 6, 2006
Messages
110
Website
Visit site
Hi, I am try to allocate memory for two objects at the same time. This is so that I can quickly reference to the second object by pointer arithmetic.

For example
CODE

void *memory = malloc(sizeof(int) + sizeof(char));

int *firstPart;
char *secondPart;
char *pointArith;

firstPart = memory;
pointArith = memory + sizeof(int);
secondPart = pointArith;

*firstPart = 4;
*secondPart = 'L';

printf("firstPart %d, secondPart %c\n",*firstPart,*secondPart); /* Test to see if they have been assigned
correct values (Which it does) */

free(firstPart);
free(secondPart);




When running the debugger it crashes when freeing the secondPart. Is this because free() will try and release memory that is sizeof(int) + sizeof(char) bytes long instead of sizeof(char) bytes?

So I just need to use free once for the firstPart and there will be no memory leak?
 

yaustar

UK GP32 & GP2X Owner
Joined
Oct 18, 2003
Messages
2,714
Location
UK
Website
Visit site
QUOTE
So I just need to use free once for the firstPart and there will be no memory leak?

Yes (sortof), for every one malloc, you use one free. Therefore, you should be freeing *memory and not any of the other pointers:
CODE
free( memory );
 

rabidcow

Still Fresh
Joined
Nov 12, 2005
Messages
56
Uprising said:
Hi, I am try to allocate memory for two objects at the same time. This is so that I can quickly reference to the second object by pointer arithmetic.
You might consider using a struct, eg:
CODE
struct Pair
{
int firstPart;
char secondPart;
};

struct Pair *pair = malloc(sizeof(struct Pair));
pair->firstPart = 4;
pair->secondPart = 'L';

free(pair);


Uprising said:
When running the debugger it crashes when freeing the secondPart. Is this because free() will try and release memory that is sizeof(int) + sizeof(char) bytes long instead of sizeof(char) bytes?

So I just need to use free once for the firstPart and there will be no memory leak?
To be more precise, you need to pass the pointer that you got from malloc to free. You can't free just any block of memory, only exactly memory received from malloc.
 
Last edited by a moderator:

skeezix

Internal Development
Joined
Mar 11, 2003
Messages
8,063
Website
www.codejedi.com
As rabidcow notes; re: "so that I can quickly reference to the second object by pointer arithmetic" .... why? There are some obscure reasons you might want to do this, but not very many ;)

Note that when you do a malloc of say (example) 20 bytes, malloc actually allocates a bit more and stores some of its own information in the front. Then it gives you your piece back.

ex:

malloc 20 might allocate 50 bytes (just making it up here), and then it gives you back ptr+30, so you see your 20 bytes, but it can figure out _its_ 30 bytes by subtrraction. When you called free with a bad value, it finds junk and explodes.

Treat malloc and free as giving you handles to data; you can do what yuou like int he area pointed to, but you cannot just willy nilly pass any old thign to free.. can only pass back what you were given.

jeff
 

Squidge

Certified Guru
Joined
Nov 16, 2003
Messages
8,493
Location
UK
Website
Visit site
QUOTE
Treat malloc and free as giving you handles to data; you can do what yuou like int he area pointed to, but you cannot just willy nilly pass any old thign to free.. can only pass back what you were given.


But some implementations of "free" do accept "NULL" as a parameter and don't crash. I wouldn't depend on this however and always check pointers are not null before free'ing them.

Oh, and whilst your there, always always check the return code from malloc! Null pointer dereferencing can wreck havoc!
 

skeezix

Internal Development
Joined
Mar 11, 2003
Messages
8,063
Website
www.codejedi.com
<off topic>

Squidge .. heres a trick I use; it hurts peoples brains, but it works and is pretty simple really.

Given a struct, and you want to know how many bytes into it a member lies, without using offset_of or other kludges.

struct mypoop *p = NULL;
unsigned int offset_to_foo = &(p.foo)

Given p points to NULL (zero), the address of a member works out to be the offset.

For some reason, I love that trick.

jeff
 

Squidge

Certified Guru
Joined
Nov 16, 2003
Messages
8,493
Location
UK
Website
Visit site
Heh, I've done that before, then someone else took my code, obviously thought that part was in error, malloc'd first, and then wondered why it didn't work any more :D
 

Quiest

I like turtles!
Joined
Sep 2, 2004
Messages
3,411
Age
39
Location
Dteuschland ;)
skeezix said:
struct mypoop *p = NULL;
unsigned int offset_to_foo = &(p.foo)
Pretty interesting, but why does that work o_O
Since p is pointing at nothing, how can I check the adress of a member of the struct, when the member simply isnt there?
Even more, why can you use p.foo and don't have to use p->foo?

Sorry if this is some noobish sort of question ^^
 
Last edited by a moderator:

sbseb88

Still Fresh
Joined
Dec 22, 2006
Messages
64
Quiest said:
skeezix said:
struct mypoop *p = NULL;
unsigned int offset_to_foo = &(p.foo)
Pretty interesting, but why does that work o_O
Since p is pointing at nothing, how can I check the adress of a member of the struct, when the member simply isnt there?
Even more, why can you use p.foo and don't have to use p->foo?

Sorry if this is some noobish sort of question ^^

p is a pointer; thus it normally contains an address at which some data is stored. In this case, a struct with a couple of members. What the C compiler does to get a member of the struct, it takes the pointer and adds an offset to it, so that it "points" the member within the struct.

The compiler takes p (which is NULL) and adds the offset (to NULL) effectively giving you the offset of the member. Neat little trick, I've never seen it before :)

Oh, and I think p.foo is a typo (not sure though) it should be p->foo.
 
Last edited by a moderator:

Quiest

I like turtles!
Joined
Sep 2, 2004
Messages
3,411
Age
39
Location
Dteuschland ;)
Okay, thanks, so it takes the offset directly from the struct?
...now that I think of it, where else should it take it from :rolleyes:
 

Uprising

Member
Joined
Mar 6, 2006
Messages
110
Website
Visit site
Thanks for the replys all. :)

I have made sure I am checking if the pointers are NULL now. :D

The reason I want to do this is because I am trying to create a simple memory tracker that keeps hold of any memory allocated with malloc in a linked list.

Whenever I needed to free memory the function had to search through the entire list until the data in the list matched the memory address to free.

So instead of doing that I can just use pointer arithmetic (since I have allocated memory for both the list and the data in one go) to find and unlink the list, then free both memory and list.

I hope that makes sense, I can put up the malloc and free functions if you want.


To clarify, free needs the head address of the memory malloc returned in order to work? (Ignoring the fact that malloc creates memory before the address it returns)

void *memory = malloc(bytes);

int *intPointer = memory;
char *charPointer = memory;
void *voidPointer = memory;

So it is safe to free from any of those pointers because they all contain the same address returned by malloc?
 

Squidge

Certified Guru
Joined
Nov 16, 2003
Messages
8,493
Location
UK
Website
Visit site
Uprising said:
To clarify, free needs the head address of the memory malloc returned in order to work? (Ignoring the fact that malloc creates memory before the address it returns)

So it is safe to free from any of those pointers because they all contain the same address returned by malloc?
Correct!

However,

QUOTE
The reason I want to do this is because I am trying to create a simple memory tracker that keeps hold of any memory allocated with malloc in a linked list.


Why reinvent the linked list? If you want a simple linked list that allows you to immediately find an item quickly, and remove it from the list, take a look at 'map' in the standard template library. It'll do what your trying to do now without all the hassle, and it can find stuff much quicker than searching through every object.

http://www.cprogramming.com/tutorial/stl/stlmap.html
 
Last edited by a moderator:

skeezix

Internal Development
Joined
Mar 11, 2003
Messages
8,063
Website
www.codejedi.com
Exploring on your own is okay; have fun :p

But I'd still use a linked list or some other storage mechanism to keep track of allocs done, and don't other with the ptr arith. ie: You're mixing up two problems -- one is to track your ree/allocs to ensur you didn't forget a free, and the other is writing a primitive memory manager. Do one or the other or both, but only as you need. You're doing both, when it sounds like you want one.

You could also do something like..

#define mymalloc(x) malloc(x);printf("malloc size %u at line " __LINE__, x)

(that sort of thing)

Then when you run it, you get a printf stdout list of allocs, and at what line, say.

Do the same for free().

(you could use fprintf to a file, too, and so on.)

Then you just run the output through a sort and can find the ones with missing pairs, say. (malloc without a free)

Some people further extend it to..

#define mymalloc(reason,size) ...

So they can printf "reason" like:

void *p = mymalloc ( "Get RAM for screen buf", 1000 );

etc..

jeff
 

charlieb

Member
Joined
Nov 30, 2006
Messages
116
Squidge said:
But some implementations of "free" do accept "NULL" as a parameter and don't crash. I wouldn't depend on this however and always check pointers are not null before free'ing them.
<hair split>Actually implementations are required to not crash when freeing a NULL, (free(0x0) not to be confused with a pointer to nowhere) but they are allowed to report the error and terminate (which actually might as well be a crash).</hair split>

Sorry, I was reading the C standard for some reason the other day.

Charlieb
 
Last edited by a moderator:

Uprising

Member
Joined
Mar 6, 2006
Messages
110
Website
Visit site
I would use the standard template library but I am coding in C and have not learnt the ways of C++ yet. :)

Thanks for the suggestions skeezix using defines looks to be a good way of tracking and I wasn't aware of the predefined macros.
 

Squidge

Certified Guru
Joined
Nov 16, 2003
Messages
8,493
Location
UK
Website
Visit site
You don't really have to learn the ways of C++, you can write your programs in C if you want, and just use snippets of C++, although you'll soon find the use of things like namespaces, classes, etc advantageous.

If you want to write it yourself however, no problem!
 

YakumoFuji

Member
Joined
Sep 30, 2005
Messages
189
just be aware that his macro is a multiline macro so such like

CODE

if(blah == blahblah)
q = mymalloc(1000);



can print results for an uninitialized variable....


what I would suggest, for C, use this ( http://directory.fsf.org/memwatch.html )

you just do include "memwatch.h" and compile memwatch.c with your app... voila! instant mem logging you will see what was not freed up etc.

CODE

- ANSI C
- Logging to file or user function using TRACE() macro
- Fault tolerant, can repair it's own data structures
- Detects double-frees and erroneous free's
- Detects unfreed memory
- Detects overflow and underflow to memory buffers
- Can set maximum allowed memory to allocate, to stress-test app
- ASSERT(expr) and VERIFY(expr) macros
- Can detect wild pointer writes
- Support for OS specific address validation to avoid GP's (segmentation faults)
- Collects allocation statistics on application, module or line level
- Rudimentary support for threads (see FAQ for details)
- Rudimentary support for C++ (disabled by default, use with care!)
- ...and more
 

charlieb

Member
Joined
Nov 30, 2006
Messages
116
YakumoFuji said:
you just do include "memwatch.h" and compile memwatch.c with your app... voila! instant mem logging you will see what was not freed up etc.
Valgrind is also an excellent memory checker tool that doesn't require and re-compilation. It runs on Linux on the PC but a memory leak is the same on any platform.
 
Last edited by a moderator:

Sphinxter

Says What?
Joined
Oct 1, 2006
Messages
2,894
Location
Silicon Valley California, USA
Website
fullsack.com
skeezix said:
As rabidcow notes; re: "so that I can quickly reference to the second object by pointer arithmetic" .... why? There are some obscure reasons you might want to do this, but not very many ;)
Because you can. Hot damn I love C.

CODE


short i, x, y;
double **array; // dynamic matrix

array = ( double **)malloc( y * sizeof( double *));
*array = ( double * )malloc( x * y * sizeof( double ));
for( i = 1; i < y; ++i )
*( array + i ) = *( array + i - 1 ) + x;

array[ y ][ x ] = 12345.123;




code not compiled nor claimed to, ymmv
 
Last edited by a moderator:

Uprising

Member
Joined
Mar 6, 2006
Messages
110
Website
Visit site
Squidge said:
You don't really have to learn the ways of C++, you can write your programs in C if you want, and just use snippets of C++, although you'll soon find the use of things like namespaces, classes, etc advantageous.

If you want to write it yourself however, no problem!
I must admit I do find it interesting understanding how they are implemented. :)
Although it can get frustrating quickly hehe.

YakumoFuji thanks for the suggestion, memwatch is maybe a bit much for what I need though but it does look very good.

Valgrind is something that I want to try out, going to have to install linux one day. :p

Thanks again all.
 
Last edited by a moderator:
Top