Thread: Segfault

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    25

    Segfault

    I am receiving a Segmentation Fault on line 11. There might be something wrong with the way i am compiling it because this is the first time that i have used terminal. At any rate, the segfault is in line 11 and i have never had this problem before. Let me know what you think.
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    struct integer 
    {
        int *digits;
        int size;
    };
    
    void print(struct integer *p)
    {
        int i;
    
        for (i = p->size - 1; i >= 0; i--)
            printf("%d", p->digits[i]);
    }
    
    struct integer *convert_integer(char *stringInt)
    {
        int i;
    
        struct integer *p = malloc(sizeof(struct integer));
    
        p->size = strlen(stringInt);
        p->digits = malloc(sizeof(int) * p->size);
    
        for (i = 0; i < p->size; i++)
            p->digits[i] = stringInt[p->size - 1 - i] - '0';
    
        return p;
    }
    
    int isZero(struct integer *p)
    {
        return (p->size == 1 && p->digits[0] == 0);
    }
    
    struct integer *multiply(struct integer *p, struct integer *q)
    {
        int i, j, carry;
    
        struct integer *m;
    
        // Terminate early in special case of multiplication by zero
        if (isZero(p) || isZero(q))
            return convert_integer("0");
    
        // Create struct to hold product
        m = malloc(sizeof(struct integer));
        m->size = p->size + q->size;
        m->digits = calloc(m->size, sizeof(int));
    
        // Perform multiplication; don't worry about addition overflows yet
        for (i = 0; i < q->size; i++)
            for (j = 0; j < p->size; j++)
                m->digits[i + j] += q->digits[i] * p->digits[j];
    
        // Compensate for addition overflows
        for (i = carry = 0; i < m->size; i++)
        {
            m->digits[i] += carry;
            carry        = m->digits[i] / 10;
            m->digits[i] = m->digits[i] % 10;
        }
    
        // Strip leading zero if it exists
        if (m->digits[m->size - 1] == 0)
            m->size--;
    
        return m;
    }
    
    struct integer *destroy_integer(struct integer *p)
    {
        free(p->digits);
        free(p);
        return NULL;
    }
    
    int main(void)
    {
        int N, i;
        char buffer[10001];
        struct integer *p, *q, *m;
        
        FILE *ifp = fopen("bigint.rft", "r");
    
        fscanf(ifp, "%d", &N);
        for (i = 1; i <= N; i++)
        {
            fscanf(ifp, "%s", buffer);
            p = convert_integer(buffer);
    
            fscanf(ifp, "%s", buffer);
            q = convert_integer(buffer);
    
            m = multiply(p, q);
    
            // Problem Output
            printf("Problem #%d: ", i);
            print(p);
            printf(" * ");
            print(q);
            printf(" = ");
            print(m);
            printf("\n");
    
            // Memory Management
            p = destroy_integer(p);
            q = destroy_integer(q);
            m = destroy_integer(m);
        }
    
        fclose(ifp);
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Jan 2013
    Posts
    25
    it is actually occurring in line 9, sorry

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Why are you so sure it's those lines? Think about it. Line 11 is just the line describing a function. Line 9 is the closing curly brace of a struct definition.

    A seg fault happens when your program tries to access memory it doesn't have access to (e.g. read an invalid address, write to read-only memory, etc). That means that the offending line of code must actually be runnable code, i.e. a line of code that does something. Lines 11 and 9 do not do anything themselves.

    You should also learn to use a debugger, it's perhaps the most valuable tool for a programmer. It will help you track down seg faults and other problems. Take a look (gdb is my debugging program, ./foo is your program):
    Code:
    $ gdb ./foo
    GNU gdb (GDB) Fedora (7.3-43.fc15)
    Copyright (C) 2011 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i686-redhat-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /home/cagarvin/sandbox/cprogramming/foo...done.
    (gdb) r
    Starting program: /home/cagarvin/sandbox/cprogramming/foo
    [Thread debugging using libthread_db enabled]
    
    
    Program received signal SIGSEGV, Segmentation fault.
    0x4d4d00fe in __isoc99_fscanf () from /lib/libc.so.6
    Missing separate debuginfos, use: debuginfo-install cyrus-sasl-lib-2.1.23-18.fc15.i686 glibc-2.14.1-6.i686 keyutils-libs-1.2-7.fc15.i686 krb5-libs-1.9.3-2.fc15.i686 libcom_err-1.41.14-2.fc15.i686 libselinux-2.0.99-4.fc15.i686 nspr-4.9-2.fc15.i686 nss-3.13.4-2.fc15.i686 nss-softokn-freebl-3.13.4-1.fc15.i686 nss-util-3.13.4-2.fc15.i686 openldap-2.4.24-3.fc15.i686 openssl-1.0.0j-1.fc15.i686 postgresql-libs-9.0.8-1.fc15.i686 zlib-1.2.5-3.fc15.i686
    (gdb) bt
    #0  0x4d4d00fe in __isoc99_fscanf () from /lib/libc.so.6
    #1  0x0804897b in main () at foo.c:89
    (gdb) fr 1
    #1  0x0804897b in main () at foo.c:89
    89          fscanf(ifp, "%d", &N);
    (gdb) p ifp
    $1 = (FILE *) 0x0
    That loads your program in the debugger.
    That runs your program.
    That gives a backtrace, i.e. a list of which functions are calling which functions at the point of the crash.
    That is your seg fault.
    That is the offending line, line 89.
    That takes me to stack frame #1, the main() function.
    That prints the value of ifp, which is NULL (0x0).

    Now, line 89
    Code:
    fscanf(ifp, "%d", &N);
    Something there is not right. In my case, it turns out ifp is NULL, because I don't have bigint.rft and so fopen failed. You need to check the return value of all IO functions. If they fail, print a useful error (try the perror() function, or look into errno and strerror()). Then, act accordingly, either return from your function with an error, quit the program, or take some other measure.

    Your problem may be slightly different, since you may have that file. But if you used to use an IDE and now you're compiling/running from a terminal, you may be "missing" the file too. More likely, the file is not located in the current directory when you run the program, something that may be setup differently in the IDE.

  4. #4
    Registered User
    Join Date
    Jan 2013
    Posts
    25
    thanks i need to look into it a bit more but this reply has been helpful

  5. #5
    Registered User
    Join Date
    Jan 2013
    Posts
    25
    here is my output

    (gdb) r
    Starting program: /Users/claytoncuteri/Desktop/bigint
    Reading symbols for shared libraries +............................. done

    Program received signal EXC_BAD_ACCESS, Could not access memory.
    Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000068
    0x00007fff94f12781 in __svfscanf_l ()
    (gdb) bt
    #0 0x00007fff94f12781 in __svfscanf_l ()
    #1 0x00007fff94f0e98d in fscanf ()
    #2 0x0000000100000b89 in main ()
    (gdb) fr1
    Undefined command: "fr1". Try "help".
    (gdb) fr 1
    #1 0x00007fff94f0e98d in fscanf ()
    (gdb) p ifp
    No symbol table is loaded. Use the "file" command.
    (gdb)

  6. #6
    Registered User
    Join Date
    Nov 2011
    Location
    Saratoga, California, USA
    Posts
    334
    Perhaps you should test if ifp == NULL ?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > (gdb) fr 1
    > #1 0x00007fff94f0e98d in fscanf ()
    You want to adjust your frame command to get to main, if you want to see the line of code in main which called fscanf, and thus see the value of ifp.
    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. Segfault... Why?
    By jonheese in forum C Programming
    Replies: 14
    Last Post: 11-21-2011, 06:02 PM
  2. C Segfault help
    By edishuman in forum C Programming
    Replies: 4
    Last Post: 11-03-2011, 05:08 PM
  3. another SEGFAULT
    By cerr in forum C Programming
    Replies: 8
    Last Post: 01-14-2010, 11:04 AM
  4. Sometimes segfault, sometimes not
    By jcafaro10 in forum C Programming
    Replies: 18
    Last Post: 04-07-2009, 06:53 PM
  5. Segfault
    By oddball in forum C Programming
    Replies: 2
    Last Post: 11-02-2007, 07:53 AM