Using NULL in C

mattg1981

Senior member
Jun 19, 2003
957
0
76
Here is what I have to do:

Add a clearList function that will traverse the array of strings and free the malloced strings as it goes. Set each element to NULL also. Don't forget to pass a pointer to the numWords counter .... yada yada

Here is what I have: // wordType is a struct we are using

void clearlist(wordType words[], int * numWords)
{
int k;

for (k = 0; k < *numWords; k++)
{
free(words[*numWords].word); // this is to free the malloced strings
words[*numWords] = NULL; // this is where I get my error : Line 114
}
*numWords = 0;
}

This is my error:

[mgimbl@localhost assignment4]$ make
gcc -c assign4.c
assign4.c: In function `clearlist':
assign4.c:114: error: incompatible types in assignment
make: *** [assign4.o] Error 1

Any suggestions?
 

mattg1981

Senior member
Jun 19, 2003
957
0
76
I mean .. I know its not a memory address like it is in Java .. but I thought there would be more to it than just setting it to 0
 

mattg1981

Senior member
Jun 19, 2003
957
0
76
nope .. the first one just setting = 0, I get incompatible types
the second one setting words[*numWords] = (wordType)NULL I get error: conversion to non-scalar type requested
 

dighn

Lifer
Aug 12, 2001
22,820
4
81
oops i didn't read your codee carefully

i see wordType is a struct, you cannot set a struct to "NULL" but you can zero it with memset eg memset(&amp;the_word, 0, sizeof(wordType));

but this really depends on how wordType is defined and used
 

DWW

Platinum Member
Apr 4, 2003
2,030
0
0
Originally posted by: mattg1981
oh ... so when he says set each element to NULL ... he means to set it to 0?

NULL is sometimes hand-coded as '\0' which is 0 in decimal. It isn't proper though and the programmer shouldn't (in theory) use it.

'\0' should be associated with strings (char array TERMINATION...don't get it mixed up cause you still need to use NULL in this case not \0) and the constant "NULL" should be defined with pointers.

See the code I'm attaching for your problem. Try this and tell me what it does.

Oh and what is wordType exactly? a typedef'd struct?
 

DWW

Platinum Member
Apr 4, 2003
2,030
0
0
part of the problem is that you kept refering to *numWords which is out of bounds in the array as it is

if you have 5 strings basically what you are saying is:

free(words[5].word)

5 doesn't exist to begin with (it will only go to 4). Besides you keep doing it over and over (freeing the same area of memory). Use the counter k instead of *numWords. Its an honest mistake and you are probably tired ;)
 

mattg1981

Senior member
Jun 19, 2003
957
0
76
oh yeah .. duh .. when you sit down and start coding for about 7 hours .. you start to miss little syntax like that :/

anyways ... wordType is a simple typedef, here it is:

typedef struct
{
char * word;
int count;
} wordType;

I have to use free(words[k].word) ... and then when I say words[k] = NULL this is the error I get:
error: incompatible types in assignment
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
Originally posted by: DWW
part of the problem is that you kept refering to *numWords which is out of bounds in the array as it is

if you have 5 strings basically what you are saying is:

free(words[5].word)

5 doesn't exist to begin with (it will only go to 4). Besides you keep doing it over and over (freeing the same area of memory). Use the counter k instead of *numWords. Its an honest mistake and you are probably tired ;)

That's not his problem. He's getting a compiler error, not a core dump. Such a small offset error probably wouldn't cause an error until much later anyways. His loop is correct (note the "<" not "==")

If wordType is a struct as dighn said (is it?, edit: I see it is) and you are freeing the memory referenced by a pointer contained in that struct then you want to null the pointer, not the struct itself. What you're probably looking for is:
words[*numWords].word = NULL;
NULL the pointer that you are freeing so that it doesn't point to the memory that it doesn't own anymore.

The way you have it written you are trying to set a member of your array to NULL. The problem is that it's not a pointer. Although there isn't a direct analogy for java that'd be more like trying to assign a value of null to an int. A struct is just a form of native data type.

Keep on going. When the idea of references (pointers) finally clicks just right everything becomes so clear. You'll be able to do double and triple pointer logic in your head (although that's not a good idea :confused: ) Hope this helps, good luck
 

DWW

Platinum Member
Apr 4, 2003
2,030
0
0
Originally posted by: mattg1981
oh yeah .. duh .. when you sit down and start coding for about 7 hours .. you start to miss little syntax like that :/

anyways ... wordType is a simple typedef, here it is:

typedef struct
{
char * word;
int count;
} wordType;

I have to use free(words[k].word) ... and then when I say words[k] = NULL this is the error I get:
error: incompatible types in assignment

Question: why do you have the struct wordType to begin with? What is count for? The length? Do you HAVE to use wordType in your assignment?
 

dighn

Lifer
Aug 12, 2001
22,820
4
81
Originally posted by: mattg1981
oh yeah .. duh .. when you sit down and start coding for about 7 hours .. you start to miss little syntax like that :/

anyways ... wordType is a simple typedef, here it is:

typedef struct
{
char * word;
int count;
} wordType;

I have to use free(words[k].word) ... and then when I say words[k] = NULL this is the error I get:
error: incompatible types in assignment

setting words[k].word = NULL; and words[k].count = 0; should suffice

NULL should not be used on non-pointers
 

DWW

Platinum Member
Apr 4, 2003
2,030
0
0
Originally posted by: kamper
Originally posted by: DWW
part of the problem is that you kept refering to *numWords which is out of bounds in the array as it is

if you have 5 strings basically what you are saying is:

free(words[5].word)

5 doesn't exist to begin with (it will only go to 4). Besides you keep doing it over and over (freeing the same area of memory). Use the counter k instead of *numWords. Its an honest mistake and you are probably tired ;)

That's not his problem. He's getting a compiler error, not a core dump. Such a small offset error probably wouldn't cause an error until much later anyways. His loop is correct (note the "<" not "==")

The loop is correct but he is nonetheless trying to access part of the array that is non-existant. Beside the fact the logic in the code was wrong. It should still be the counter k obviously.
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
My guess is he's trying to count occurences of certain words in a list or paragraph. word would indicate which word is being counted and count would indicate how many times it's been found. Am I close?
 

mattg1981

Senior member
Jun 19, 2003
957
0
76
yeah ... some little program that reads in a paper or some large text and organizes the text into an array or wordTypes (multiples do not take up two array spots but just increase the count number)
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
Originally posted by: DWW
Originally posted by: kamper
Originally posted by: DWW
part of the problem is that you kept refering to *numWords which is out of bounds in the array as it is

if you have 5 strings basically what you are saying is:

free(words[5].word)

5 doesn't exist to begin with (it will only go to 4). Besides you keep doing it over and over (freeing the same area of memory). Use the counter k instead of *numWords. Its an honest mistake and you are probably tired ;)

That's not his problem. He's getting a compiler error, not a core dump. Such a small offset error probably wouldn't cause an error until much later anyways. His loop is correct (note the "<" not "==")

The loop is correct but he is nonetheless trying to access part of the array that is non-existant. Beside the fact the logic in the code was wrong. It should still be the counter k obviously.

Heh, good point, I didn't see that :eek:

So then we're in agreement that he should be nulling words[k].word, not words[k] itself. Does this solve your problem mattg?
 

mattg1981

Senior member
Jun 19, 2003
957
0
76
It compiled using kampers words[*numWords].word = NULL; way ... and now that I think about it .. that makes sense. Becuase the words is just a local array of wordTypes and that is automatic not dynmaic so that will get destroyed by the compiler or whatever .. the only dynamic memory I had was the ptr to word.words .. so freeing that is all I need to do I believe.

Only thing is in class, we were talking about using free(node) .. so what I did was this:
free(words[k].word); and it compiled and runs ... I just wish I had a program that detected memory leaks so I knew if it was getting unmalloced or whatever you want to call it
 

mattg1981

Senior member
Jun 19, 2003
957
0
76
I just compiled it using DWW's method of

free(words[k].word);
words[k].word = NULL;

and that worked too ... so let me see if I have this right:

free(words[k].word) -> frees or unmalloces the memory that I owned .. (what exactly does this mean though? ... did I just kill the pointer to it or did I erase what was in that memory address or did I just tell the OS .. "HERE you go, I dont need it anymore")

and then the words[k].word = NULL ... I dont know what I need this really .. I just freed it in the line above ... could you explain this one please :)
 

DWW

Platinum Member
Apr 4, 2003
2,030
0
0
Originally posted by: mattg1981
It compiled using kampers words[*numWords].word = NULL; way ... and now that I think about it .. that makes sense. Becuase the words is just a local array of wordTypes and that is automatic not dynmaic so that will get destroyed by the compiler or whatever .. the only dynamic memory I had was the ptr to word.words .. so freeing that is all I need to do I believe.

Only thing is in class, we were talking about using free(node) .. so what I did was this:
free(words[k].word); and it compiled and runs ... I just wish I had a program that detected memory leaks so I knew if it was getting unmalloced or whatever you want to call it

Arrays are not local when passed in, in the C language. An array is just a pointer (think like object references in Java). The words array won't be destroyed in the clearList function but it will in the calling piece of code that created it.

Yes you must destroy each word if it was created using malloc.

But you still cant't use words[*numWords].word = NULL because you want to set each individual one to NULL and *numWords is constant-like in this case. You need to use the counter k.
 

kamper

Diamond Member
Mar 18, 2003
5,513
0
0
One method I was taught was to track down every place you use malloc() or free() and print the value of the pointer involved to sterr along with whether it was an allocation or a deallocation. Then when you run your program redirect sterr to a file and read the file afterwards. Match up the pointer values and you will be able to tell which ones were allocated but never deallocated. It's a bit of a hassle but it's much simpler than including a memory leak library, especially when you're just learning. If you don't mind a small mess in your code you can wrap the fprintf in an #ifdef DEBUG block and leave it there. Then it will only get compiled in when you define DEBUG at compile time. I'd suggest using grep to find all occurences of malloc() and free(). Just remember to be carefull if you're using realloc() as well. Then you might want two print statements (one before and one after). Read the man page, realloc's a funny one.
 

mattg1981

Senior member
Jun 19, 2003
957
0
76
oh yeah .. I totally understand about the *numWords and k deal ... that was just a logic error on my part that I overlooked
 

mattg1981

Senior member
Jun 19, 2003
957
0
76
Hey guys, you were a huuuuuuuuuge help ... thank you soooooo much.

BTW .. DWW, how do you put that code in the forum?