C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 05-14-2008, 04:38 PM   #1
Registered User
 
Join Date: May 2008
Location: Kentucky
Posts: 13
the basics of malloc

I've enjoyed many of your posts and decided to register and pick your minds if you don't mind.

Somehow I've managed to program for a LONG time and never bothered to understand some things. All too often I've done "just make it work" programming.

I'm working on a program now and noticing things I just think I should understand. For example, here's a line from a program:

note[ctr].nBody = (char *) malloc (100 * sizeof( char ) ) ;

The structure for note is:
Code:
typedef char *STRING

typedef struct noteinfo {	       /* structure of note		*/
	int    nSize;				/* number of characters in note body	*/
	STRING nBody;	 		  /* text of note					*/
	STRING nExtra;			  /* area for extra info such as date string	*/
} NOTEINFO;
So, later when I'm ready to write the file I wanted to test the note body (note[ctr].nBody) to see if it was empty. I expected to be able to see if it was empty by using

Code:
if( note[ctr].nBody == NULL )
But it turns out that there are four chars in .nBody even though I've done nothing with it since the malloc and sizeof() also returns a size of 4.

Can anyone tell me what malloc puts in the string during malloc? And, how might I test note[ctr].nBody to see if it is empty? (Empty meaning nothing has been done to it since the malloc.) I've tested for content using lstrlen(), which returns 0. But that seems kinda sloppy.

Thanks,
Dale L
nakedBallerina is offline   Reply With Quote
Old 05-14-2008, 04:46 PM   #2
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 14,785
Using sizeof on a pointer will typically return 4 or 8, depending on the size of a pointer on the system. So in other words, you are getting the size of the pointer, and not the actual value or data stored there.
But if you do sizeof(*nBody), you will get 1 ( sizeof(char) ), because the compiler cannot know how many elements or how big the data block pointed to by the pointer is.
Malloc only returns NULL if it fails, so you can't check for NULL either.
Therefore, the better solution is to keep track of whether or not something has been written. But you do have a "nSize" variable, so use that (ie nSize == 0).

Also beware that typedefing a pointer may not be the greatest idea. It will probably introduce confusion, so avoid that.
And "n" isn't a typical prefix for a string. It's more of a prefix for numbers.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 05-14-2008, 05:59 PM   #3
Registered User
 
Join Date: May 2008
Location: Kentucky
Posts: 13
Elysia, thank you. As I read your reply I was banging my head and saying "I knew that." All too often I get caught in the act of thinking content or value rather than pointer. This probably comes from the many years (most of my first ten years of programming) of writing in REXX which is so forgiving that you rarely use pointers.

Thanks.

Now, I'll have to figure out a good way to phrase my questions on win32's WriteFile function when using structures. I remember quite quickly concluding "this is nuts" and going right back to fopen and fwrite and fputs and the likes.

Dale L
nakedBallerina is offline   Reply With Quote
Old 05-14-2008, 06:00 PM   #4
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 14,785
But fopen/fwrite are C standard functions, WriteFile is not. You would be sacrificing portability.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 05-14-2008, 06:13 PM   #5
Registered User
 
Join Date: May 2008
Location: Kentucky
Posts: 13
Elysia, agreed. Hence my copies of K&R and Petzold are pretty much resident on my desk. Going through Petzold it is obvious that he is trying to remain win32 compliant. So one day I get to playing with WriteFile and seems that things blow up.

For example, from the structure in the code above. Lets say I have

NOTEINFO note[NumberOfNotes] ;

NumberOfNotes may be pretty much any number: lets say 25.

Now, I want to drop all 25 of the notes to file using WriteFile. I remember playing with it for quite a while and got unexpected results. Probably forgot about pointers again.

It would seem that there would be a nice quick and easy one liner to write the 25 notes to file. Any chance you have that one liner on the tip of your tongue?

Dale L
nakedBallerina is offline   Reply With Quote
Old 05-14-2008, 06:15 PM   #6
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 14,785
For C:
fwrite(note, sizeof(note), 1, f);

Only works if note is defined in the same function where you write the file. Otherwise you're going to have to do something like:
fwrite(note, sizeof(*note) * num, 1, f);
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 05-14-2008, 06:27 PM   #7
Registered User
 
Join Date: May 2008
Location: Kentucky
Posts: 13
Elysia, yes. Thanks. I've got it all working in standard C routines. I was curious as to how it would be done with win32's WriteFile. I pulled the following line from some old code that didn't work:

WriteFile (hFile, note[ctr], sizeof(note[ctr]), &dwBytesWritten, NULL) ;

Don't knock yourself out on this one. Just toying with things that I've done in the past in, perhaps, far less than professional style.

Dale L
nakedBallerina is offline   Reply With Quote
Old 05-14-2008, 06:30 PM   #8
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 14,785
Try this instead:
Code:
WriteFile (hFile, note, sizeof(note), &dwBytesWritten, NULL) ;
It's basically the same as the C code.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 05-15-2008, 02:11 AM   #9
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Bear in mind that writing a struct that contains pointers to a binary file is pretty useless, because if when you load the data next time, the pointers will not be valid [1]. You need to either:
1. Use fixed length strings in your note data.
This is by far the easiest to implement.

2. Write the data out in a different way (so you store the string pointed to by the pointer, rather than the pointer itself).
This is trickier, but also more flexible as it copes with any length body/extra, as you have to know how much data you have to read, so you first read the nSize, then allocate nSize bytes for nBody, and read nSize bytes into your new pointer, and finally you need to know the length of nExtra and do the same thing there.

[1] Of course, if you don't de-allocate the memory (or exit the application), it will still be valid if when you read it back - but the point of storing something is usually that you want to exit the application and then read it back when you start the application again.

--
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.
matsp is offline   Reply With Quote
Old 05-16-2008, 05:29 PM   #10
Registered User
 
Join Date: May 2008
Location: Kentucky
Posts: 13
Thanks for the input. While the WriteFile line I gave was not quite a real life example, your comments certainly did help shake the cobwebs and clear things up. Thanks.

Now, if you don't mind, another concern.

Somewhere I've read that after doing a malloc (or alloc) it is good to set the variable value to NULL such as:

Code:
note[ctr].nBody = malloc (300 * sizeof( char ) ) ;
note[ctr].nBody = NULL ;
Okay, that kinda makes sense. As I understand, it would leave the var pointing to nothing. Would this be done to help in the area of memory leaks? Is this a good practice? Would I really want to bother setting to NULL if I'm actually going to fill the nBody immediatly after the malloc?

Thoughts are appreciated.

Dale L
nakedBallerina is offline   Reply With Quote
Old 05-16-2008, 05:32 PM   #11
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 14,785
Yes, it's a good practice. However, you must free it first, otherwise you get a memory leak.
It allows you to see if it's a valid pointer or not, which is why it's such a good thing.
Don't do it right after malloc (your memory you just allocated will be lost!).
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 05-16-2008, 05:38 PM   #12
Registered User
 
Join Date: May 2008
Location: Kentucky
Posts: 13
Let me make sure I understand: setting it to NULL will actually defeat the malloc? So if I set nBody to NULL before doing anything with it I would be defeating the malloc?

In other words, I would want to first do malloc on nBody and then not until after done using nBody, I would free it and then set it to NULL?

Dale L
nakedBallerina is offline   Reply With Quote
Old 05-16-2008, 05:39 PM   #13
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 14,785
Yes to first and second.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 05-16-2008, 06:09 PM   #14
Guest
 
Sebastiani's Avatar
 
Join Date: Aug 2001
Posts: 5,034
>> Somehow I've managed to program for a LONG time and never bothered to understand some things. All too often I've done "just make it work" programming.

it's pointless to program in a language you don't understand so well. you will spend a lot of time debugging problems that would have never been an issue had you just consulted a good C programming book.

>> Okay, that kinda makes sense. As I understand, it would leave the var pointing to nothing. Would this be done to help in the area of memory leaks? Is this a good practice? Would I really want to bother setting to NULL if I'm actually going to fill the nBody immediatly after the malloc?

seriously.
Sebastiani is offline   Reply With Quote
Old 05-16-2008, 10:52 PM   #15
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,710
Code:
note[ctr].nBody = malloc (300 * sizeof( char ) ) ;
Now do something with your 300 chars.

Then when you're done, you do this.
Code:
free( note[ctr].nBody );
note[ctr].nBody = NULL ;
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
malloc + segmentation fault ch4 C Programming 5 04-07-2009 03:46 PM
Is there a limit on the number of malloc calls ? krissy Windows Programming 3 03-19-2006 12:26 PM
Malloc and calloc problem!! xxhimanshu C Programming 19 08-10-2005 05:37 AM
malloc() & address allocation santechz C Programming 6 03-21-2005 09:08 AM
malloc always setting length of 8? Zarkhalar C++ Programming 7 08-01-2004 11:36 PM


All times are GMT -6. The time now is 05:06 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22