c - Segmentation fault (core dumped) error for selection sort pointer char array -


when compile , run selection sort of random char array segmentation fault (core dumped) error. think it's got accessing unallocated memory in selection sort section. can please?

#include <stdio.h> #include <stdlib.h> #include <string.h>  #define string_len 80 #define array_len 10000  void *emalloc(size_t s) {    void *result = malloc(s);    if (null == result) {       fprintf(stderr, "memory allocation failed!\n");       exit(exit_failure);    }    return result; }  void selection_sort(char *words[], int n) {    char *temp;    int i, j;     (i = 0; < n; i++) {       (j = i+1; < n; j++) {          if (strcmp(words[i], words[j]) < 0) {             temp = words[i];             words[i] = words[j];             words[j] = temp;          }       }    } }  int main(void) {    char word[string_len];    char *wordlist[array_len];    int num_words;    int i;     num_words = 0;    while (num_words < array_len && 1 == scanf("%79s", word)) {       wordlist[num_words] = emalloc((strlen(word) + 1) * sizeof wordlist[0][0]);       strcpy(wordlist[num_words], word);       num_words++;    }     selection_sort(wordlist, num_words);     (i = 0; < num_words; i++) {        printf("%s\n", wordlist[i]);    }     (i = 0; < num_words; i++) {       free(wordlist[i]);    }     return exit_success; } 

instead of pointing out simple hard-to-spot error, i'm going walk through how debugged can learn how use debugger , solve these types of issues (teach man fish, saying goes).

first, compiled code (with warning level cranked up) , made sure reproduce issue:

$ clang test.c -o test -wall -wextra -pedantic  # no warnings, great! $ echo -e 'foo\nbar\nbaz' | ./test segmentation fault: 11 

ok, crashed. issue reproducible. now, recompile debug symbols (-g) , setup test vector:

$ clang test.c -o test -wall -wextra -pedantic -g $ echo -e 'foo\nbar\nbaz' > input 

now run debugger , see happens. i'm using lldb on mac os x, exact same commands work in gdb:

$ lldb ./test current executable set './test' (x86_64). (lldb) run < input process 68367 launched: './test' (x86_64) process 68367 stopped * thread #1: tid = 0x553a95, 0x00007fff918e0db5 libsystem_platform.dylib`_platform_strcmp + 181, queue = 'com.apple.main-thread', stop reason = exc_bad_access (code=1, address=0x0)     frame #0: 0x00007fff918e0db5 libsystem_platform.dylib`_platform_strcmp + 181 libsystem_platform.dylib`_platform_strcmp + 181: -> 0x7fff918e0db5:  movdqu (%rsi,%rcx), %xmm1    0x7fff918e0dba:  pcmpeqb %xmm1, %xmm0    0x7fff918e0dbe:  pcmpeqb %xmm2, %xmm1    0x7fff918e0dc2:  pandn  %xmm0, %xmm1 

we crashed inside strcmp() function on null pointer (the address=0x0 part). how did there , why did happen? here's stack trace:

(lldb) bt * thread #1: tid = 0x553a95, 0x00007fff918e0db5 libsystem_platform.dylib`_platform_strcmp + 181, queue = 'com.apple.main-thread', stop reason = exc_bad_access (code=1, address=0x0)   * frame #0: 0x00007fff918e0db5 libsystem_platform.dylib`_platform_strcmp + 181     frame #1: 0x0000000100000c96 test`selection_sort(words=0x00007fff5fbec1a0, n=3) + 86 @ test.c:23     frame #2: 0x0000000100000e03 test`main + 243 @ test.c:45 

let's move called strcmp():

(lldb) 1 frame #1: 0x0000000100000c96 test`selection_sort(words=0x00007fff5fbec1a0, n=3) + 86 @ test.c:23    20       21      (i = 0; < n; i++) {    22         (j = i+1; < n; j++) { -> 23            if (strcmp(words[i], words[j]) < 0) {    24               temp = words[i];    25               words[i] = words[j];    26               words[j] = temp; 

now let's see calling strcmp() (p shorthand print):

(lldb) p words[i] (char *) $0 = 0x0000000100103920 "foo" (lldb) p words[j] (char *) $1 = 0x0000000000000000 

welp, there's our null pointer. how did happen? i , j?

(lldb) p (int) $2 = 0 (lldb) p j (int) $3 = 3 

oh no! j 3, shouldn't ever 3 or more, since n 3 (since had 3 lines in input file). shouldn't our loop prevent j exceeding n...? take closer look:

22            (j = i+1; < n; j++) { 

oops—there's bug. loop test i < n when should j < n. j grows without bound until crashes or else bad happens (like attacker taking on system if input data specially crafted exploit this).

here links learn how use command line debuggers such lldb , gdb:


Comments

Popular posts from this blog

java - How to specify maven bin in eclipse maven plugin? -

single sign on - Logging into Plone site with credentials passed through HTTP -

php - Why does AJAX not process login form? -