Thread: Segmentation Fault

  1. #1
    Registered User
    Join Date
    Jul 2013
    Posts
    8

    Segmentation Fault

    Hi need help. I can't understand why my program keeps on getting "Segmentation Fault". The last time I checked (in UBUNTU) it was already working, now I'm testing it in Windows and I keep on getting "Segmentation Fault".

    Code:
    #include <stdio.h>
    #include <string.h>
         
     
    int main(){
    char string[1500];
    char word[100];
    int i,x,y,keyword=0,operator=0,s=0;
    char *result;
    char delims[] = "  \n";
    char *keywords[] = {"auto", "break", "else", "case", "char", "const", "continue", "default", "do", "double",             "enum","extern","float","for","goto","if","int","long","register","return","short","signed",
            "sizeof","static","struct","switch","typedef","union","unsigned","void","volatile","while",
            "_Bool","_Complex","_Imaginary","inline","restrict","NULL"};
    char *operators[]={"+", "-", "*", "/", "%","=","+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=",
            "~", "&", "|", "^" ,"<<", ">>" ,"!", "&&", "||","?:", "==", "!=","( )","++", "--",".", "->",
            "<", "<=", ">", ">=", "*", "[ ]",",","(typename)","NULL"};
            
    
    
        printf("Enter Paragraph which can include spaces and Any number of lines.\n");
        printf("To terminate  press TAB and Enter.\n");
        scanf("%[^\t]",string);
        
        //Count the number of lines
        for(i=0;string[i]!='\0';++i) { 
        if (string[i]=='\n') ++s; } 
        printf("\nNo. of lines: %d\n",s); 
        
        //Tokenies paragraph
        strcpy(word, result);
        result = strtok( string, delims );
            while( result != NULL ) {
        strcpy(word, result);
        
        //Count number of keywords
            for( x = 0; keywords[ x ] != "NULL"; x++ ){   
            if ( strcmp ( word, keywords[x]) == 0 )
                keyword++;
            }
            
        //Count number of operators
            for( y = 0; operators[ y ] != "NULL"; y++ ){   
            if ( strcmp ( word, operators[y]) == 0 )
                operator++;
            }
               
        result = strtok( NULL, delims );
        }
        printf( "No. of keywords: %d.\n", keyword );
        printf( "No. of operators: %d.\n", operator );
    }

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    line 30 - result is not initialized
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Quote Originally Posted by vart View Post
    line 30 - result is not initialized
    Set it to NULL since it's an unused pointer.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Depending on the input supplied to the program, scanf() can happily overflow the buffer.

    However, the most glaring problem is undefined behaviour on line 30. strcpy(word, result) copies from result to word. result is an uninitialised pointer. Setting result to NULL won't work, since strcpy() also has undefined behaviour if either argument is NULL.

    It is no surprise that the program fails under windows. I find it difficult to believe your claim that it worked at all under ubuntu.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    The main point to make here is that you should turn up your compiler warning level. For gcc, try
    gcc -Wall -Wextra yourprog.c

  6. #6
    Registered User
    Join Date
    Jul 2013
    Posts
    8
    So can you explain why did this work??? because I can't figure out why. And I guess it's not because "result" was not initialized

    Code:
    #include <stdio.h>
    #include <string.h>
         
     
    int main(){
    char string[1500];
    char word[10];
    int i,x,y,keyword=0,operator=0,s=0;
    char *result;
    char delims[] = "  \n";
    char *keywords[] = {"auto", "break", "else", "case", "char", "const", "continue", "default", "do", "double","enum","extern","float","for","goto","if","int","long","register","return","short","signed",
            "sizeof","static","struct","switch","typedef","union","unsigned","void","volatile","while",
            "_Bool","_Complex","_Imaginary","inline","restrict","NULL"};
    /*char *operators[]={"+", "-", "*", "/", "%","=","+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>=",
            "~", "&", "|", "^" ,"<<", ">>" ,"!", "&&", "||","?:", "==", "!=","( )","++", "--",".", "->",
            "<", "<=", ">", ">=", "*", "[ ]",",","(typename)","NULL"};*/
            
    
    
        printf("Enter Paragraph which can include spaces and Any number of lines.\n");
        printf("To terminate  press TAB and Enter.\n");
        scanf("%[^\t]",string);
        
        //Count the number of lines
        for(i=0;string[i]!='\0';++i) { 
        if (string[i]=='\n') ++s; } 
        printf("\nNo. of lines: %d\n",s); 
        
        //Tokenies paragraph
        strcpy(word, result);
        result = strtok( string, delims );
            while( result != NULL ) {
        strcpy(word, result);
        
        //Count number of keywords
            for( x = 0; keywords[ x ] != "NULL"; x++ ){   
            if ( strcmp ( word, keywords[x]) == 0 )
                keyword++;
            }
            
    /*    //Count number of operators
            for( y = 0; operators[ y ] != "NULL"; y++ ){   
            if ( strcmp ( word, operators[y]) == 0 )
                operator++;
            }*/
               
        result = strtok( NULL, delims );
        }
        printf( "No. of keywords: %d.\n", keyword );
        printf( "No. of operators: %d.\n", operator );
    }

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Obviously it's possible for that line not to crash, but it's still a glaring error. Remove it and instead do
    word[0] = '\0';

    Also, comparing to the string literal "NULL" will only work if string literals are pooled.
    It's more usual to use NULL, not "NULL".
    Try removing the quotes from around all your NULL's.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Gaily Guzon
    So can you explain why did this work??? because I can't figure out why.
    By luck, it appeared to work. One characteristic of undefined behaviour is that it sometimes seems to work. Unfortunately, it has a tendency of failing to work when you are demonstrating the program to your teacher or to the boss/client.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Jul 2013
    Posts
    8
    Thank you to all of you, it worked! You guys are very helpful. I learned a lot today.

  10. #10
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    So can you explain why did this work???
    Plain dumb luck. Look at these warnings my compiler spits out.
    ||=== c_homework, Debug ===|
    main.c||In function ‘main’:|
    main.c|36|warning: comparison with string literal results in unspecified behavior [-Waddress]|
    main.c|8|warning: unused variable ‘y’ [-Wunused-variable]|
    main.c|30|warning: ‘result’ is used uninitialized in this function [-Wuninitialized]|
    ||=== Build finished: 0 errors, 3 warnings (0 minutes, 5 seconds) ===|
    That's the thing about undefined behavior, your program may appear to work today but tomorrow who knows.

    If your not getting these warnings you need to increase your compiler warning levels.

    By the way the undefined behavior is using the uninitialized pointer in the strcpy(). Why are you calling this function at this place (line 30) in your program?

    Jim

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    In addition to compiling with as many warnings as possible, and then fixing them, the next useful tool to apply is valgrind.
    Code:
    $ valgrind ./a.out
    ==2786== Memcheck, a memory error detector
    ==2786== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
    ==2786== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
    ==2786== Command: ./a.out
    ==2786== 
    Enter Paragraph which can include spaces and Any number of lines.
    To terminate  press TAB and Enter.
    int main ( ) {
    if ( argc == NULL )
    }
    
    	
    
    No. of lines: 4
    ==2786== Use of uninitialised value of size 8
    ==2786==    at 0x4C29781: strcpy (mc_replace_strmem.c:311)
    ==2786==    by 0x400808: main (in /home/sc/Documents/a.out)
    ==2786== 
    ==2786== Invalid read of size 1
    ==2786==    at 0x4C29781: strcpy (mc_replace_strmem.c:311)
    ==2786==    by 0x400808: main (in /home/sc/Documents/a.out)
    ==2786==  Address 0x90 is not stack'd, malloc'd or (recently) free'd
    ==2786== 
    ==2786== 
    ==2786== Process terminating with default action of signal 11 (SIGSEGV)
    ==2786==  Access not within mapped region at address 0x90
    ==2786==    at 0x4C29781: strcpy (mc_replace_strmem.c:311)
    ==2786==    by 0x400808: main (in /home/sc/Documents/a.out)
    ==2786==  If you believe this happened as a result of a stack
    ==2786==  overflow in your program's main thread (unlikely but
    ==2786==  possible), you can try to increase the size of the
    ==2786==  main thread stack using the --main-stacksize= flag.
    ==2786==  The main thread stack size used in this run was 8388608.
    ==2786== 
    ==2786== HEAP SUMMARY:
    ==2786==     in use at exit: 0 bytes in 0 blocks
    ==2786==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
    ==2786== 
    ==2786== All heap blocks were freed -- no leaks are possible
    ==2786== 
    ==2786== For counts of detected and suppressed errors, rerun with: -v
    ==2786== Use --track-origins=yes to see where uninitialised values come from
    ==2786== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)
    Segmentation fault
    You can even instruct valgrind to drop into the debugger at the first sign of trouble.

    Even if your buffer overruns or whatever do not cause a crash, many mistakes will be spotted by valgrind.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. segmentation fault
    By nils8950 in forum C Programming
    Replies: 20
    Last Post: 12-20-2012, 01:27 PM
  2. arg SEGMENTATION FAULT!
    By rocomotion in forum C Programming
    Replies: 2
    Last Post: 09-23-2009, 06:27 AM
  3. Help on Segmentation Fault!!!
    By SweeLeen in forum Linux Programming
    Replies: 4
    Last Post: 02-19-2006, 11:33 AM
  4. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  5. segmentation fault and memory fault
    By Unregistered in forum C Programming
    Replies: 12
    Last Post: 04-02-2002, 11:09 PM