Ошибка сегментации в C при инициализации массива - PullRequest
0 голосов
/ 19 октября 2019

Я пытаюсь динамически создать массив в отдельной функции и сохранить некоторые переменные внутри этого массива, и я столкнулся со следующим: как получается, когда я пишу;

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

void foo(int **arr, int N) {
  *arr = malloc(sizeof(int));

  for (int index = 0; index <= 4; index++) {
    *arr[index] = 1;
  }
}

int main() {
  int *arr; 
  foo(&arr, 5);

  for (int bar = 0; bar <= 4; bar++) {
    printf("%d ", arr[bar]);
  }
}

Я получаю этот вывод;

exited, segmentation fault

Однако, когда я запускаю следующее:

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

void foo(int **arr, int N) {
  *arr = malloc(sizeof(int));
}

int main() {
  int *arr; 
  foo(&arr, 5);

  for (int index = 0; index <= 4; index++) {
    arr[index] = 1;
  }

  for (int bar = 0; bar <= 4; bar++) {
    printf("%d ", arr[bar]);
  }
}

я получаю этот вывод;

1 1 1 1 1

Я застреваю, пытаясь выяснить, как исправитьпервый блок кода, чтобы заставить его работать, но я, кажется, понятия не имею, как это сделать. Любая помощь будет полезна, по крайней мере, для понимания причин возникновения ошибки сегментации.

Ответы [ 2 ]

1 голос
/ 20 октября 2019

Здесь происходит пара вещей, которые являются важными деталями.

Евгений прав, что вам нужно выделить N вещей размера int. В противном случае ваша программа неверна и будет записывать в недопустимые места в памяти.

Причину нарушения сегмента потребовалось несколько минут для поиска. Я добавил операторы printf в ваш код, чтобы увидеть, где произошло нарушение сегмента. Это показало, что присвоение 1 элементу массива было именно там, где оно происходило.

Затем я подозревал, что проблема связана с порядком привязки / порядка, поэтому поместите круглые скобки вокруг * arr, чтобы было очень ясно, что онбыло намерение. Нарушение сегмента ушло после этого. Я также изменил инициализацию на индекс, чтобы результаты назначения были легко проверяемыми.

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

void foo(int **arr, int N) 
{
    *arr =(int *) malloc(sizeof(int) * N);

    for (int index = 0; index < N; index++)
    {
        printf("before assignment\n");
        (*arr)[index] = index;
        printf("after assignment\n");
    }
}

int main() 
{
  int *arr; 
  foo(&arr, 5);

  for (int bar = 0; bar < 5; bar++) 
  {
    printf("%d ", arr[bar]);
  }
}

Короче говоря, полезный быстрый и грязный метод заключается в вставке набора printfs, чтобы помочь сузить место возникновения проблемы. .

0 голосов
/ 20 октября 2019

malloc требует полного объема памяти, включая размер массива. Таким образом, правильный код будет

*arr = malloc(sizeof(int) * N);
...