Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Why segfault and no NULL match in for loop?

Reply
Thread Tools

Why segfault and no NULL match in for loop?

 
 
somebody
Guest
Posts: n/a
 
      05-02-2007
There are two files below named search.c and search.h.
In the for loop in search.c, the for loop never exits,
even if mystruct[i].field1 has no match. Instead of
exiting the for loop it keeps going until it segfaults.
This seems to be related to the strcmp with the NULL
value. There are 2 comments below that indicate
the segfaults. I guess the question is, when there
is no match, how to I detect that and return without
a segfault?

-Thanks


SEARCH.C ----------------------------------------

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "search.h"


int search(char * field1)
{
int i = 0;


/* This is never = to NULL, even when no match for field1 */

for(i=0; mystruct[i].field1 != NULL; i++) {

if(strcmp(field1, mystruct[i].field1) == 0) {
return(mystruct[i].numfield);
}


/*THIS SEGFAULTS ALWAYS!!!!*/
/*if (strcmp(mystruct[i].field1, NULL) == 0) {*/
/*}*/

}

return(0);
}



int main(void)
{
int retval = 0;

/* THIS CAN CAUSE SEGFAULT TOO!!! */
/*This works if you match, for example, CCC. But if*/
/*you change the CCC to say YYY, which is not in the*/
/*struct, it segfaults.*/

char str[] = "CCC";

retval = search(str);

printf("retval = %d\n", retval);

return 0;
}


SEARCH.H -----------------------------


struct _mystruct
{
char field1[4];
char field2[4];
char field3[2];
char field4[3];
int numfield;
};


struct _mystruct mystruct[] =
{
"AAA", "EEE", "R", "DF", 25,
"BBB", "FFF", "R", "DF", 25,
"CCC", "GGG", "R", "DF", 99,
"DDD", "HHH", "R", "DF", 13,
};
 
Reply With Quote
 
 
 
 
Walter Roberson
Guest
Posts: n/a
 
      05-02-2007
In article <(E-Mail Removed)>,
somebody <(E-Mail Removed)> wrote:
>There are two files below named search.c and search.h.
>In the for loop in search.c, the for loop never exits,
>even if mystruct[i].field1 has no match. Instead of
>exiting the for loop it keeps going until it segfaults.
>This seems to be related to the strcmp with the NULL
>value.


>int search(char * field1)
>{
> int i = 0;
>


> /* This is never = to NULL, even when no match for field1 */


> for(i=0; mystruct[i].field1 != NULL; i++) {


If you examine your mystruct data, you will see that you do not
have any entries in which mystruct[<anything>] == NULL .
You therefore iterate off the end of mystruct[], and start
testing a non-existant mystruct[i].field1 entry.


> if(strcmp(field1, mystruct[i].field1) == 0) {
> return(mystruct[i].numfield);
> }


> }
> return(0);
>}



>struct _mystruct
>{
> char field1[4];
> char field2[4];
> char field3[2];
> char field4[3];
> int numfield;
>};
>
>
>struct _mystruct mystruct[] =
>{
> "AAA", "EEE", "R", "DF", 25,
> "BBB", "FFF", "R", "DF", 25,
> "CCC", "GGG", "R", "DF", 99,
> "DDD", "HHH", "R", "DF", 13,
>};



--
Programming is what happens while you're busy making other plans.
 
Reply With Quote
 
 
 
 
Richard Tobin
Guest
Posts: n/a
 
      05-02-2007
In article <f1b4ns$6lt$(E-Mail Removed)>,
Walter Roberson <(E-Mail Removed)-cnrc.gc.ca> wrote:

>> /* This is never = to NULL, even when no match for field1 */

>
>> for(i=0; mystruct[i].field1 != NULL; i++) {


>If you examine your mystruct data, you will see that you do not
>have any entries in which mystruct[<anything>] == NULL .
>You therefore iterate off the end of mystruct[], and start
>testing a non-existant mystruct[i].field1 entry.


And since mystruct is an array, you can just loop over its known
length:

for(i=0; i<sizeof(mystruct)/sizeof(mystruct[0]); i++)

>>struct _mystruct


Don't use names starting with underscore, they're reserved.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      05-02-2007
somebody wrote:

> There are two files below named search.c and search.h.
> In the for loop in search.c, the for loop never exits,
> even if mystruct[i].field1 has no match. Instead of
> exiting the for loop it keeps going until it segfaults.
> This seems to be related to the strcmp with the NULL
> value. There are 2 comments below that indicate
> the segfaults. I guess the question is, when there
> is no match, how to I detect that and return without
> a segfault?
>
> -Thanks
>
>
> SEARCH.C ----------------------------------------
>
> #include <string.h>
> #include <stdlib.h>
> #include <stdio.h>
>
> #include "search.h"
>
>
> int search(char * field1)
> {
> int i = 0;
>
>
> /* This is never = to NULL, even when no match for field1 */
>
> for(i=0; mystruct[i].field1 != NULL; i++) {


When will your conditional ever be true? Those character arrays can
NEVER be NULL. You need to add another "blank" array entry, and test
for an empty string or something.

for(i=0; mystruct[i].field1[0] != '\0'; i++) {


>
> if(strcmp(field1, mystruct[i].field1) == 0) {
> return(mystruct[i].numfield);
> }
>
>
> /*THIS SEGFAULTS ALWAYS!!!!*/
> /*if (strcmp(mystruct[i].field1, NULL) == 0) {*/
> /*}*/


Well, yeah. NULL is not a string, and passing a null pointer to most of
the string-handling routines causes undefined behavior. To test for a
null pointer (which you can't have), use equality.

> struct _mystruct
> {
> char field1[4];
> char field2[4];
> char field3[2];
> char field4[3];
> int numfield;
> };
>


Try adding:

> struct _mystruct mystruct[] =
> {
> "AAA", "EEE", "R", "DF", 25,
> "BBB", "FFF", "R", "DF", 25,
> "CCC", "GGG", "R", "DF", 99,
> "DDD", "HHH", "R", "DF", 13,

"", "", "", "", 0
> };




Brian

 
Reply With Quote
 
Default User
Guest
Posts: n/a
 
      05-02-2007
Richard Tobin wrote:


> And since mystruct is an array, you can just loop over its known
> length:
>
> for(i=0; i<sizeof(mystruct)/sizeof(mystruct[0]); i++)



True, but only because he has global data. As soon as he moves that
array into main() or another function and passes it into search() as he
should, he'll be right back where he started. He could add a size
parameter, of course, or use a sentinel value like he tried and failed
to do.





Brian
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-03-2007
CBFalconer <(E-Mail Removed)> writes:
[...]
> NEVER define an actual object in a .h file. Doing so will cause it
> to be multiply defined, and result in link or run time errors. Add
> the word "extrn" to the definition, and delete the initialization.
> Put the above structure in ONLY one of the files in which you
> #include "search.h".


It's "extern", not "extrn".

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
jaysome
Guest
Posts: n/a
 
      05-03-2007
On Wed, 02 May 2007 20:14:34 -0400, CBFalconer <(E-Mail Removed)>
wrote:

>somebody wrote:
>>
>> There are two files below named search.c and search.h. In the for
>> loop in search.c, the for loop never exits, even if
>> mystruct[i].field1 has no match. Instead of exiting the for loop
>> it keeps going until it segfaults. This seems to be related to the
>> strcmp with the NULL value. There are 2 comments below that
>> indicate the segfaults. I guess the question is, when there is no
>> match, how to I detect that and return without a segfault?
>>

>... snip to content of search.h ...
>>
>> struct _mystruct mystruct[] =
>> {
>> "AAA", "EEE", "R", "DF", 25,
>> "BBB", "FFF", "R", "DF", 25,
>> "CCC", "GGG", "R", "DF", 99,
>> "DDD", "HHH", "R", "DF", 13,
>> };

>
>NEVER define an actual object in a .h file. Doing so will cause it
>to be multiply defined, and result in link or run time errors. Add
>the word "extrn" to the definition, and delete the initialization.
>Put the above structure in ONLY one of the files in which you
>#include "search.h".


In addition to the correction noted by Keith ("extrn" should be
"extern"), it should be noted that defining an actual object in a .h
file does not necessarily mean that it will be multiply defined and
result in a link or run time error.

If the header file is included by a single translation unit, there
will be no link or run time errors. You only run into trouble when
multiple translation units include said header file and *think* they
are accessing the same data (something I have witnessed in practice).

Why would you ever want to define an actual object in a .h file? I can
think of only one instance, which is if the .h file is shared between
two or more programs (and included by a single translation unit in
each, of course). I've used this technique, but only sparingly. Think
of gcc and gcov using the same objects with file scope internal
linkage, as an example (I'm not saying they do this, just that it is
an acceptable option, IMHO, especially if there are a lot of the same
objects used in both).

(My actual usage of the above is almost the same code running as
programs/processes on two dissimilar processors, which was one of the
requirements necessary to achieve a certain level of system safety
assurance).

NEVER define an actual object in a .h file, unless you really know
what you're doing.

>A .h file is NOT a place for headers, it is a place to define the
>data you want to export from a .c file.


Saying a ".h file is NOT a place for headers" is like saying a "house
is not a place for a home". I think you meant "objects" instead of
"headers".

Best regards
--
jay
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-03-2007
CBFalconer <(E-Mail Removed)> writes:
> jaysome wrote:
>> CBFalconer <(E-Mail Removed)> wrote:
>>

> ... snip ...
>>
>>> A .h file is NOT a place for headers, it is a place to define the
>>> data you want to export from a .c file.

>>
>> Saying a ".h file is NOT a place for headers" is like saying a
>> "house is not a place for a home". I think you meant "objects"
>> instead of "headers".

>
> No, I wrote what I meant. I mean you don't just collect all the
> headers and export them to a .h file. You only export those that
> are needed elsewhere.


I think the point is that a .h file (almost always) *is* a "header".
Are you using the term "header" in some other sense?

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
invoking a segfault within a segfault handler - is this undefinedbehavior? Andrey Vul C Programming 8 07-30-2010 02:14 PM
vector has segfault null dereference andrey.vul@gmail.com C++ 6 10-03-2007 01:45 AM
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
"stringObj == null" vs "stringObj.equals(null)", for null check?? qazmlp1209@rediffmail.com Java 5 03-29-2006 10:37 PM



Advertisments