#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2005
    Location
    London, UK
    Posts
    207
    Rep Power
    10

    ANSI C - Check for Null in char


    Hi,

    How on earth do I check whether a returned value is Null?

    Using (well, attempting to) plain old C for this.

    Trying:
    if (strcmp(sVal1, NULL) == 0)
    // Found NULL.

    But, get memory access violation. sVal1 is defined as char *sVal1;

    Any ideas?

    Cheers,
    J
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    sVal1 is a pointer and you're wanting to test whether that pointer is set to NULL.

    Therefore:
    if (sVal1 == NULL)
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2005
    Location
    London, UK
    Posts
    207
    Rep Power
    10
    Hi mate,

    Cheers for that! Perhaps it's a good time to ask why? I had to declare it as a pointer because the function (that returns the value). Is that the common rule for a pointer? You can check their values outright instead of having to use one of the str* type of functions?

    Cheers
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    This is basic knowledge, so please review your C reference's intro coverage of pointers. I don't know what your level of knowledge is, so please forgive me if I talk down below your level here.

    Basically, a pointer is a variable whose value is a memory address. You can either work with its own value, which is a memory address, or with the data contained at that memory address. I guess that's a possible point to confuse: a pointer's value is a memory address and is not to be confused with the value that it's pointing to, which is the data stored at that memory location.

    When a function returns a pointer value, then that is to be assigned to a pointer variable and it becomes that pointer's value. One of those possible values is NULL, which is used by convention to indiciate that the pointer isn't pointing to anything (I say "by convention" because we have to explicitly set an unused pointer to NULL; an uninitialized pointer could point to anywhere). So if you need to test whether a pointer is set to a particular value (most often we will test for NULL), then you compare the pointer variable to that value; eg:
    if (sVal1 == NULL)

    On the other hand, many functions are not interested in the pointer itself, but rather in the data that it's pointing to. For example, the str* type of functions are only interested in the char data that is stored at the memory location that the pointer is pointing to. For that reason, you would not use a str* type function to test the value of the pointer itself. Indeed, if that pointer was set to NULL, then the str* function would be looking at invalid "data", so it is necessary to test the pointer and ensure that it is a valid pointer before passing it to a str* function.

    Did that help?

    Comments on this post

    • codergeek42 agrees : A polite , informative, and straightfoward reply. Excellent. :)
    Last edited by dwise1_aol; April 19th, 2006 at 01:24 PM.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2005
    Location
    London, UK
    Posts
    207
    Rep Power
    10
    Hi mate,

    Thank you very much for taking the time to respond to me. What you've said has made perfect sense. I have a much clearer picture now.

    One question though, within the statement:
    if (strcmp(sVal1, NULL) == 0)

    is true to say that I'm comparing the char sVal1 (which I'm assuming is irrelevant whether it's a pointer or not) to NULL (which is interpreted as a pre defined pointer to no value)?

    Yes, I'm very much a novice and do need to read up on this. Have been lumbered with a scripting tool at work that uses C so need to come to terms with it all.

    Again, thank you very much!

    Cheers,
    J
  10. #6
  11. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,607
    Rep Power
    4247
    Originally Posted by Jonesin2005
    One question though, within the statement:
    if (strcmp(sVal1, NULL) == 0)

    is true to say that I'm comparing the char sVal1 (which I'm assuming is irrelevant whether it's a pointer or not) to NULL (which is interpreted as a pre defined pointer to no value)?
    Not quite. strcmp() is a function that compares two char arrays. One of the features of C is that whenever a function is called with array variables as parameters, the function doesn't actually receive the array. Instead, it receives a pointer to the FIRST element of the array alone. This makes it more efficient since the function can reference the entire array as long as it knows where it starts in memory.

    So, when you call strcmp(sVal1, NULL), the strcmp function receives two values. It expects that these are pointers to the first element of two arrays. It then iterates through memory locations hoping to compare the contents of these two arrays. This is where problems occur, because it is never a good idea to dereference NULL (i.e.) determine what is really stored in the contents of address NULL. In some cases, the value is 0 and so strcmp() stops comparing right there. If it is non-zero, who knows what happens!
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  12. #7
  13. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Originally Posted by Jonesin2005
    One question though, within the statement:
    if (strcmp(sVal1, NULL) == 0)

    is true to say that I'm comparing the char sVal1 (which I'm assuming is irrelevant whether it's a pointer or not) to NULL (which is interpreted as a pre defined pointer to no value)?
    Since I wouldn't even attempt something like that, I cannot speak from experience but rather have to hypothesize.

    I would say that strcmp() is instead comparing to each other character-by-character the strings being pointed to by the two pointers being passed to it. That is to say that you are telling it that the first string is located at the address stored in sVal1 and the second string is at memory location zero (which is the value of NULL). So it is going to try to look at location zero for the first character and it will try to go on from there. Since location zero is where the Interrupt Vector Table (a big list of memory addresses) starts, I can guarantee that there are no character strings located there, even though strcmp() would try to interpret the address data there as character strings.

    I've been saying "try" because that part of memory is protected; for one thing that area is absolutely vital to the operation of the computer and if your program were to change anything there it would cause the system to crash -- for another, that is how memory is organized now, so that your app is assigned its own block of memory and is not allowed to access anybody else's (as I understand it; my main experience is from DOS, which is pre-protected-memory). I know that you will get a run-time "segmentation fault" if you try to write to location zero, but since I don't attempt such things I'm not sure if you'd also get a seg-fault for attempt to read from that location.

    So, attempting to use NULL as a pointer means you are trying to access location zero (0000:0000 in the old segmented memory systems, eg Win16; I'm not sure what the address notation is in the flat memory model of Win32).

    Were you thinking of how to specify an empty string? One that contains no characters? That would be "", as in
    if (strcmp(sVal1,"") == 0)
    to test whether sVal1's string is the empty string. The empty string does have memory assigned to it and it does have a valid pointer pointing to it and it contains a single character, NUL (the character value '\0', not to be confused with the pointer value NULL), which is the null-terminator that C uses to mark the end of a string. It is because of the null-terminator that, when you allocate a buffer for a string, you must always make the buffer one character larger than the largest possible string it could hold, in order to reserve space for the null-terminator.
    Last edited by dwise1_aol; April 19th, 2006 at 07:28 PM.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Posts
    399
    Rep Power
    0
    Just to help maybe get a better picture, let's say you have this:

    Code:
    char str[4];
    str[0] = 'a';
    str[1] = 'b';
    str[2] = 'c';
    str[3] = '\0';
    str is now "abc\0" which makes it "abc" to any function.

    let's say you declare a pointer:

    Code:
    char *ptr = str;
    then ptr is the memory address of str[0]; (which is 'a')..

    Code:
    ptr = 975; //memory address of str[0]
    this makes this statement true..

    Code:
    *ptr = 'a';
    The fun thing about pointers is you can play with a string by going anywhere in the array with it and basically doing whatever you want. If you want the count of the length of "str", just increment the pointer by 1 until it finds '\0'.. in this case

    Code:
    while(*ptr) //while the value ptr is pointing to is non-zero
    {
       ptr++; //increment the memory address by 1
       count++; //increment count to keep count of the number of non-zero characters it finds
    }
    count is normal integer declared at 0. Here is a small program I just made to help you understand the different aspects of a pointer, once you get the hang of it, you can search for more advanced tutorials on them, there is much to learn.

    Code:
    #include <stdio.h>
    
    int main() 
    {
    	int count = 0;
    	char str[4];
    	str[0]= 'a';
    	str[1]= 'b';
    	str[2]= 'c';
    	str[3]= '\0';
    
    	char *ptr = str;
    	while(*ptr)
    	{
    		ptr++;
    		count++;
    	}
    
    	return count;
    }
    Compile it and run it, and examine it.. you will see it always exits with code 3 because that is the count of the string, playing around with it will help you understand it more perhaps..

    By the way, if this little tutorial is below your skills, I apologize. But it may indeed help another newbie out with this problem. I do hope this helps you a bit.

    Jon
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2005
    Location
    London, UK
    Posts
    207
    Rep Power
    10
    Jon and Scorpions4ever,

    Thanks again for the info and the working examples. Very informative and indeed helpful.

    I think it will just take it's time but is handy having experts on here. I have nobody to help out at work and can be a bit frustrating.

    Cheers,
    J
  18. #10
  19. Titles are useless ;)
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2003
    Location
    Germanski West
    Posts
    216
    Rep Power
    15
    Like explained pointers are simply addresses, i.e. numbers
    And one may also "work" with numbers ;)
    Code:
    #include <iostream>
    static size_t my_strlen(const char *in)
    {
    	const char *p = in - 1;
    	while(*++p);
    	return (size_t)(p - in);
    }
    int main(int argc, char* argv[])
    {
    	using namespace std;
    	
    	const char *test = "a test";
    	cout << "c_strlen:  " << strlen(test) << endl;
    	cout << "my_strlen: " << my_strlen(test) << endl;
    	cout << "empty:     " << my_strlen("") << endl;
    
    	getchar(); // just here so that we do not return immediately. :p
    	return 0;
    }
    PS: This is not ANSI C anymore, because of the use <iostream> which is c++... but nevermind, this is just a demonstration and that part is not the critical point. ;)
    Last edited by MaierMan; April 20th, 2006 at 11:20 AM.

IMN logo majestic logo threadwatch logo seochat tools logo