2017-02-11 4 views
3

Я пишу небольшую программу для практики malloc и sscanf функции библиотеки. Но, к сожалению, я получаю ошибку ошибки сегментации. Я гугл и боролся часами, но без результата. Кто-нибудь может привести меня к этому?Что вызывает ошибку ошибки сегментации в этой крошечной программе 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 * а = (INT *) таНос (м * SizeOf (INT *));' Вы выделяете массив для размера ' m' указатели, а не 'm'' int '. – 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. Отбрасывание возвращаемого значения malloc() не обязательно в C и считается плохим. Кроме того, вы должны проверить наличие отказа. Используйте вместо этого:

    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 имеет неопределенное значение, как вы не инициализировать его.

в sscanf вы используете &a[index], но index не был инициализирован, поэтому его можно написать где угодно.

См. Также комментарии, которые идентифицируют больше ошибок (например, проверка возвращаемого значения sscanf).

3

Ваш malloc неисправен. Заменить int* a = (int*)malloc(m*sizeof(int*)); на int* a = (int *)malloc(m*sizeof(int));. Вам повезло, что sizeofint меньше, чем int*, иначе вы можете получить целую кучу проблем.

Я не мог воспроизвести ошибку, лучше дать ввод текста в следующий раз, но для отладки segfault i зависит от gdb.

$ НКУ -g prog.c -o прог

$ GDB прог

GDB> запустить [арг]

Это нарушит программу на линии, которая вызывает Segfault. Используйте этот учебник для получения дополнительных знаний. gdb tutorial

Смежные вопросы