2017-02-11 33 views
3

我正在寫一個小型c程序來練習mallocsscanf庫函數。但不幸的是,我得到了分段錯誤錯誤。我用Google搜索了幾個小時,但沒有結果。任何人都可以把我帶出來嗎?在這個微小的c程序中導致分段錯誤的原因是什麼?

#include <stdio.h> 
#include <stdlib.h> 

void print_array(int a[], int num_elements); 

int main(void) { 
    int m;  
    printf("How many numbers do you count: \n"); 
    scanf("%d", &m); 
    int *a = (int*)malloc(m * sizeof(int*)); 
    char buf[100]; 
    setbuf(stdin, NULL); 
    if (fgets(buf, sizeof buf, stdin) != NULL) { 
     char *p = buf; 
     int n, index; 
     while (sscanf(p, "%d %n", &a[index], &n) == 1 && index < m) { 
      // do something with array[i] 
      index++; // Increment after success @BLUEPIXY 
      p += n; 
     } 
     if (*p != '\0') 
      printf("you are giving non-numbers, will be ignored"); 
    } 

    print_array(a, m); 
    free(a); 
    return 0; 
} 

void print_array(int a[], int num_elements) { 
    int i; 
    for (i = 0; i < num_elements; i++) { 
     printf("%d ", a[i]); 
    } 
} 
+2

'INT * A =(INT *)malloc的(M *的sizeof(INT *));'您正在分配的陣列用於'大小m'指針,而不是'm'' int's。 – BoBTFish

+1

'int n,index;' - >'int n,index = 0;' – BLUEPIXY

+0

'sscanf(p,「%d%n」,&a [index],&n)== 1 && index < m' -->'index BLUEPIXY

回答

1

你的程序中有多處錯誤:

  • 你不檢查的scanf()返回值。輸入無效將導致m未初始化,分配m * sizeof(int)可能會失敗。

  • 針對malloc計算的尺寸不正確。在C中鑄造返回值malloc()並不是必需的,並且被認爲是不好的風格。此外,你應該檢查分配失敗。使用這個來代替:

    int *a = malloc(m * sizeof(int)); 
    
  • index未初始化的sscanf(p, "%d %n", &a[index], &n)肯定導致未定義的行爲,你告訴sscanf()int值存儲到內存中的一些隨機地址。

  • 您測試index < m存儲到&a[index],導致潛在的緩衝區溢出。在sscanf()前交換測試。

這裏是一個修改後的版本:

#include <stdio.h> 
#include <stdlib.h> 

void print_array(const int a[], int num_elements); 

int main(void) { 
    int m;  
    printf("How many numbers do you count:\n"); 
    if (scanf("%d", &m) != 1 || m <= 0) { 
     fprintf(stderr, "invalid input\n"); 
     return 1; 
    } 
    int *a = malloc(m * sizeof(int)); 
    if (a == NULL) { 
     fprintf(stderr, "memory allocation failed\n"); 
     return 1; 
    } 
    char buf[100]; 
    setbuf(stdin, NULL); // why do you want stdin to be unbuffered? 
    if (fgets(buf, sizeof buf, stdin) != NULL) { 
     char *p = buf; 
     int n, index = 0; 
     while (index < m && sscanf(p, "%d %n", &a[index], &n) == 1) { 
      // do something with array[i] 
      index++; // Increment after success @BLUEPIXY 
      p += n; 
     } 
     if (*p != '\0') { 
      printf("you are giving non-numbers or extra input, will be ignored\n"); 
     } 
    } 

    print_array(a, m); 
    free(a); 
    return 0; 
} 

void print_array(const int a[], int num_elements) { 
    for (int i = 0; i < num_elements; i++) { 
     printf("%d ", a[i]); 
    } 
    printf("\n"); 
} 
0

多數[潛力]錯誤的原因似乎來自未初始化的自動變量:

scanf("%d",&m); 

如果失敗,則m有一個未定義的值,你沒有初始化。

in sscanf您使用&a[index],但index尚未初始化,因此它可以在任何地方寫入。

另請參閱評論,以確定更多錯誤(例如檢查返回值sscanf)。

3

您的malloc有問題。將int* a = (int*)malloc(m*sizeof(int*));替換爲int* a = (int *)malloc(m*sizeof(int));。 你在這裏很幸運,那sizeofint小於int*,否則你可能會遇到一大堆問題。

我無法重現錯誤,下次更好地給出輸入文本,但要調試segfault我依賴於gdb。

$ GCC -g prog.c中-o PROG

$ GDB PROG

GDB>運行[參數]

這將破壞在線,這是造成段錯誤程序。使用本教程獲取更多知識。 gdb tutorial

相關問題