Thread: mystery seg fault o' tha day

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    mystery seg fault o' tha day

    I have a function that I'm using to shuffle the nodes in a linked list. It takes a pointer to the head node and the length of the list as an argument. It works fine, repeatedly, on all kinds of lists UNLESS the list length is slightly over 1 million (which is several hundred megs out of 2G local RAM). Then the whole program seg faults immediately after the shuffle is called. gdb will just point to the first real instruction in the function as the culprit:
    Code:
    node *shuffle (node *head, int len) { 
            int i, X, r;
            node *ray[len], *tmp;
            printf("shuffle()..."); fflush(stdout);
    gdb sez:
    Program received signal SIGSEGV, Segmentation fault.
    0x0000000000402d2b in shuffle (head=0x605010, len=1050000) at linklist.c:543

    543 printf("shuffle()..."); fflush(stdout);

    1,000,000 okay. 1,050,000 no good! Note that shuffle()... does not even print!
    Last edited by MK27; 01-24-2009 at 09:17 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    That's because the failure happens when node *ray[len] completely fails to fit on the stack.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by tabstop View Post
    That's because the failure happens when node *ray[len] completely fails to fit on the stack.
    Why? Shouldn't the stack fit node *ray[len]?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,337
    The stack is nowhere near 2G. It might be 2MB. You would be better off doing malloc for your ray array.
    Mainframe assembler programmer by trade. C coder when I can.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by MK27 View Post
    Why? Shouldn't the stack fit node *ray[len]?
    I'm pretty sure you asked this question before, and I thought we figured out your stack was 4MB. Maybe it was someone else's stack, but that's already pretty large, for a stack.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Dino View Post
    The stack is nowhere near 2G. It might be 2MB. You would be better off doing malloc for your ray array.
    You mean I actually have to go:
    Code:
    node **ray=malloc(len*sizeof(node*));
    free(ray);
    well, it works anyway.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, that sort of thing would work. The reason it crashes on the call to printf is that when you call printf is the first time you actually WRITE outside of the stack-space (to store the arguments to printf, or if you have tuned it perfectly, on the actual call instruction when it pushes the return address onto the stack).

    The rule is that if you have LARGE objects, they go on the heap. Small objects, on stack. Now, what is a small or large object? Large is certainly anything bigger than a few kilobytes. Small objects are anything up to a few dozen bytes. The stuff in between is in the "grey area" where we you'd have to decide from instance to instance whether it is right to use the stack or the heap.

    Note also that if you don't know (like in this example, where len is a parameter to the function), and it is POSSIBLE that the size is LARGE, then you should use the heap, even if sometimes the object is actually in the small category [or have two variants of the code - one for small size and one for large size].

    Note that running out of stack is a BAD thing to do - there is no (good) way you can recover from a "out of stack" fault, besides exiting the thread/process.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. weird seg fault
    By Vermelho in forum C Programming
    Replies: 3
    Last Post: 05-10-2008, 08:27 PM
  3. Seg Fault Problem
    By ChazWest in forum C++ Programming
    Replies: 2
    Last Post: 04-18-2002, 03:24 PM
  4. debug program
    By new_c in forum C Programming
    Replies: 3
    Last Post: 03-18-2002, 11:50 PM
  5. Simplified code
    By soonerfan in forum C Programming
    Replies: 2
    Last Post: 12-05-2001, 03:50 PM