![]() |
| | #1 |
| Registered User Join Date: May 2008 Location: Kentucky
Posts: 13
| the basics of malloc 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;
Code: if( note[ctr].nBody == NULL ) 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 | |
| | #2 | |
| Mysterious C++ User 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:
| |
| Elysia is offline | |
| | #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 | |
| | #4 | |
| Mysterious C++ User 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:
| |
| Elysia is offline | |
| | #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 | |
| | #6 | |
| Mysterious C++ User 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:
| |
| Elysia is offline | |
| | #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 | |
| | #8 | |
| Mysterious C++ User Join Date: Oct 2007
Posts: 14,785
| Try this instead: Code: WriteFile (hFile, note, sizeof(note), &dwBytesWritten, NULL) ;
__________________ 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:
| |
| Elysia is offline | |
| | #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 | |
| | #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 ; Thoughts are appreciated. Dale L |
| nakedBallerina is offline | |
| | #11 | |
| Mysterious C++ User 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:
| |
| Elysia is offline | |
| | #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 | |
| | #13 | |
| Mysterious C++ User 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:
| |
| Elysia is offline | |
| | #14 |
| Guest 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 | |
| | #15 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,710
| Code: note[ctr].nBody = malloc (300 * sizeof( char ) ) ; Then when you're done, you do this. Code: free( note[ctr].nBody ); note[ctr].nBody = NULL ; |
| Salem is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
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 |