2017-05-26 123 views
0

我不知道什麼是錯我的代碼:分段錯誤

#include <stdio.h> 
#include <string.h> 

char* splitstr(char* str, int part, char search) { 
    char* out; 
    int i; 
    int result = 0; 
    for(i=0; str[i]!='\0'; i++) { 
     if(str[i] == search) { 
      result = 1; 
      break; 
     } 
    } 
    if(result == 0) { 
     if(part == 1) { 
      return str; 
     } else { 
      return ""; 
     } 
    } 
    int j; 
    int k; 
    if(part == 2) { 
     for(j = 0; j < i; j++) { 
      out[j] = str[j]; 
     } 
     out[j] = '\0'; 
    } else { 
     for(k = 0,j = i+1; j <= strlen(str)-1; j++, k++) { 
      out[k] = str[j]; 
     } 
     out[k] = '\0'; 
    } 
    return out; 
} 
} 

int main() { 
    printf("Starting program:\n"); 
    char* str = "Hello World!"; 
    char* a = splitstr(str, 1, ' '); 
    char* b = splitstr(str, 1, ' '); 
    printf("A is %s\n", a); 
    printf("B is %s\n", b); 
} 

它返回的輸出如下:

Starting program: 
Segmentation Fault: 11 

gdb調試後,我發現,錯誤是在線路30上發生(通過使用斷點),在循環的第一次迭代中,當它試圖設置out[0]out[k])到str[6]str[j])。爲什麼會觸發分段錯誤?我只是將字符串中的一個字符更改爲另一個字符!

+0

注意:發佈的代碼在聲明之後有一個不尋常的大括號'}':'return out;' – user3629249

回答

6

有一個在out沒有字符串。這是一個未初始化的指針,因爲沒有爲寫入分配內存,所以無法寫入。這樣做會觸發未定義的行爲,這就是您的程序崩潰的原因。

您必須分配一些,通常使用malloc()

另外,作爲一個單純的回顧鈔類,第一循環相當於:

const int result = strchr(str, search) != NULL; 
0

的主要問題是這一行:

char* out; 

只是聲明瞭一個指針,但不設置該指針指向任何特定內存(應用程序擁有的)

所以此行:

out[j] = str[j]; 

正在爲內存中的某個隨機位置分配值。

正確的VIA或者那樣的問題:

char *out[ strlen(str) +1 ]; // uses variable length array feature 

或通過:

char *out = malloc(strlen(str) +1); 
if(!out) 
{ // malloc failed 
    perror("malloc failed"); 
    exit(EXIT_FAILURE); 
} 

// implied else, malloc successful 

你的編譯器應該告訴你關於這個問題,像聲明:

filename.c:43:16: warning: 'out' may be used uninitialized in this function [-Wmaybe-uninitialized] 

編譯時,請始終啓用警告,然後修復這些警告。

(爲gcc,至少使用:-Wall -Wextra -pedantic我還使用:-Wconversion -std=gnu11

如果使用-Wconversion選項,那麼這也將是由編譯器輸出:

filename.c:51:30: warning: comparison between signed and unsigned integer expression [-Wsign-compare]