Welcome to Dream.In.Code
Getting C++ Help is Easy!

Join 136,077 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,590 people online right now. Registration is fast and FREE... Join Now!




strcmp segfault in C

 
Reply to this topicStart new topic

strcmp segfault in C, segfaults galore!

Irishancest
16 Apr, 2008 - 11:54 PM
Post #1

New D.I.C Head
*

Joined: 2 Nov, 2007
Posts: 14


My Contributions
Hey, I have a project for school where we are supposed to implement a hash function. I've got everything compiling now, but I've been fixing seg faults for several hours now and I've come to one that I don't understand at all, the strcmp function giving a segfault. as far as I can tell I actually have everything pointing to something, but I'm probably absolutely wrong about that.

Here is the hash2.c file:
CODE

/*
*  Table size = 1021;
*/
#include "hash.h"

main()
{      
    //node hashTable[];
    menu();
}

/*
* the function makes a user interface so that the user can do multiple
* functions on the hash table with easy instructions on what he/she/it
* needs to do to begin and end various functions
*/
void menu()
{    
    int condition;    
    char converted[21];
    struct node* hashArray[1021];
    do     //Sets up the menu so that the user can do multiple functions
    {      //     and choose when to end the program.
        printf("1) Press 1 to insert either a word or text file.\n");
        printf("2) Press 2 to find a word.\n");          
        printf("3) Press 3 to delete a text file.\n");          
        printf("4) Press 4 to quit.\n");          
        printf("5) Press 5 to use string converter.\n");
        scanf("%i", &condition);          
        if(condition == 1)          
        {        
            insertUI(hashArray, 1021);    
        }          
        else if (condition == 2)          
        {        
            findUI(hashArray);          
        }          
        else if (condition == 3)          
        {
            deleteUI(hashArray);          
        }    
        else if (condition == 5)  //testing string converter
        {
            printf("Please enter a string.\n");
              scanf("%s", &converted);
            asciiConverter(converted);    

        }

    }while (condition != 4);

}



struct node
{      
     char* word;
     Previous lNode;
     Next rNode;
     int total;
};

void insertHashed(char* insertedString, struct node* insertedArray[], int length)
{    
       int ishashed;
       ishashed = hash(insertedString, length);
       struct node* newNode = malloc(sizeof(struct node));
       newNode->word = insertedString;
       newNode->total++;
       struct node* nNode = insertedArray[ishashed];
       if(nNode == NULL)
       {
              insertedArray[ishashed] = newNode;
       }
       else
       {
              struct node* currentNode = insertedArray[ishashed];//malloc(sizeof(struct node));
            //  currentNode =
/**********************************************
*This is the section where the string compare is giving
*me the segfault, although I am sure it would happen
*int the find function as well
**********************************************/
               if(strcmp(insertedString, currentNode->word) != 0)
              {
                     while(currentNode->rNode != NULL)
                     {
                            currentNode = currentNode->rNode;
                     }
                     currentNode->rNode = newNode;
              }
              else
              {
                     currentNode->total++;
              }
       }
}

struct node* find(char* foundString, struct node* foundArray[])
{    
       int position;
       position = hash(foundString);
       struct node* found = foundArray[position];
       if (found != NULL)
       {
              if(strcmp(foundString, found->word) != 0)
              {
                     int endnow = 0;
                     while(found->rNode != NULL)
                     {                        
                            if(strcmp(foundString, found->word) != 0)
                            {
                                   found = found->rNode;
                                   endnow = 0;
                            }
                            else
                            {
                                   endnow = 1;
                                   printf("Word found.  %i occurences.", found->total);
                            }
                            if(endnow == 1)
                                      break;
                     }
                     if(endnow == 1)
                     {
                            return found;
                     }
                     else
                     {
                            struct node* notFound;
                            notFound = NULL;
                            printf("Object not found!");
                            return notFound;
                     }
              }        
       }
       else
       {
               struct node* notFound;
               notFound = NULL;
               printf("Object not found!");
               return notFound;
       }
}


int removeNode(char* removedString, struct node* removedArray[])
{
       struct node* ispresent;
       ispresent = find(removedString, removedArray);
       if(ispresent == NULL)
       {
              return -1;
       }
       else
       {
              struct node* temp;
              temp = ispresent->lNode;
              temp->rNode = ispresent->rNode;
              return 1;
       }
}

int readTextfile()
{
       FILE* fin;
       char* userFILEname;
       printf("Please type the name sf the file.");
       scanf("%i", &userFILEname);
       fin = fopen(userFILEname, "r");
}

int hash(char* hashed, int length)
{
       int hashvalue;
       hashvalue = asciiConverter(hashed);
       hashvalue = length % hashvalue;
       return hashvalue;  
}

int chain(struct node* hashEntry, struct node* newHash)
{
    while(hashEntry->rNode != NULL)
    {
        hashEntry = hashEntry->rNode;
    }
    hashEntry->rNode = newHash;
    return 1;
}

int asciiConverter(char toConvert[21])
{
    int i = 0;
    //int tot = 0;
    int ascii = 0;//malloc(sizeof(char));
    //int length = 0;
    printf("1");
    //length = strlen(toConvert);
    for(i; i < 21; i++)
    {
        printf("2");
        ascii += toConvert[i];
        printf("ASCII VALUE\n%i\n", ascii);
        //tot += ascii;
        //printf("TOT VALUE\n%i\n", tot);
    }
    printf("%i\n", ascii);
    return ascii;
}

void deleteUI(struct node* deletedArray[])
{
    char toDelete[21];
    int toContinue = 1;
    while(toContinue == 1)
    {
        printf("Please enter the name of the word you want to delete.\n");
        scanf("%s", &toDelete);
        removeNode(toDelete, deletedArray);
        printf("To delete another word press 1, otherwise press any number.\n");
        scanf("%i", &toContinue);
    }
}

void findUI(struct node* foundArray[])
{    
    int condition3;    
    do    
    {        
    printf("1) To find a word press 1.\n");        
    printf("2) To exit press 2.\n");        
    scanf("%i", &condition3);        
    if (condition3 == 1)        
    {
           char* userfind;
           printf("Please input string to find.\n");
           scanf("%i", &userfind);
           struct node* isfound;
           find(userfind, foundArray);        
    }    
    }while(condition3 != 2);
}

void insertUI(struct node* hash2Array[], int length)
{    
    int condition2;    
    do    
    {        
    printf("1) To insert a word manually please press 1.\n");        
    printf("2) To enter a text file please press 2.\n");        
    printf("3) To exit insert menu please press 3.\n");        
    scanf("%i", &condition2);        
    if (condition2 == 1)        
    {
           char fromuser[21];
           printf("Type the word to insert.\n");    
           scanf("%s", &fromuser);
           insertHashed(fromuser, hash2Array, length);    
    }        
    else if (condition2 == 2)        
    {
           readTextfile();
    }    
    }while(condition2 != 3);
}
/*#include <stdio.h>

int main( void )
{
* The file handler pointer */
//    FILE *fhp;
/* The buffer we'll read the file into */
//    char[80] str;
//    int i; /*You'll see this used in a bit*/

/* Open up a random file in read-only mode */
//    fhp = fopen( "random.file", "r" );

//    fread( str, 1, 80, fhp );
/* Alternative way:
* Uses a counter. Though be careful with
* this, as it waits for EOF from the file
* before it stops, and that could lead to
* a buffer overflow problem. If done
* correctly, you can still do this though.

* for( i = 0; str = fgetc( fhp ); i++ );

*/

/* This writes to a file if you want to
* There are two ways to do this:

* for( i = 0; str && fputc( str, fhp ); i++ );

* and

* fwrite( str, 1, 80, fhp );
*/

/* And now we close the file */
//    fclose( fhp );
//}


and here is the header hash.h
CODE

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
/*  #ifndef NULL
    #define NULL  
    #endif*/

    struct node;
    typedef struct node *Next;
    typedef struct node *Previous;
    typedef struct node *newNode;
  
    struct node* find(char* foundString, struct node* foundArray[]);
    int removeNode(char* removedString, struct node* removedArray[]);
    int readTextfile();
    void findUI(struct node* foundArray[]);
    void menu();
    void insertUI(struct node* hash2Array[], int length);
    int asciiConverter(char toConvert[21]);
    void deleteUI(struct node* deletedArray[]);
    void insertHashed(char* insertedString, struct node* insertedArray[], int length);
    int chain(struct node* hashEntry, struct node* newHash);


Thanks for any help you might be able to give me.
User is offlineProfile CardPM
+Quote Post

perfectly.insane
RE: Strcmp Segfault In C
21 Apr, 2008 - 05:48 PM
Post #2

D.I.C Addict
Group Icon

Joined: 22 Mar, 2008
Posts: 558



Thanked: 46 times
Dream Kudos: 25
Expert In: C/C++

My Contributions
QUOTE(Irishancest @ 17 Apr, 2008 - 12:54 AM) *

CODE
if (condition2 == 1)        
    {
           char fromuser[21];
           printf("Type the word to insert.\n");    
           scanf("%s", &fromuser);
           insertHashed(fromuser, hash2Array, length);    
    }  



The issue here is that the fromuser variable goes out of scope, and the memory area is not available for use (well, directly anyway) once the execution leaves this block. This is significant, as the insertHashed function does not copy the string, but it assigns the address only (to the "word" structure element). If this isn't what is actually causing the segfault, this is definitely a problem anyway. I'm surprised that one doesn't get lucky (perhaps one does, but one time, one doesn't, as the stack often has zeros on it (which is what strcmp looks for)). Actually writing to the memory area tend to be a bigger problem than reading from it in this situation (meaning, more likely to cause a crash -- overwriting return addresses).

There are a couple of solutions....

1.) Declare word to be a fixed array of characters, and use strncpy to make a copy.
2.) Dynamically allocate a character array (with new char[...], or possibly with strdup). Use strcpy to copy the string if not using strdup. Make sure that the resources are freed at the end (not a big deal as they are released anyway when the program ends, but it's a good practice).

User is offlineProfile CardPM
+Quote Post

Reply to this topicStart new topic
Time is now: 12/1/08 07:28PM

Live C++ Help!

C++ Tutorials

Reference Sheets

C++ Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month