Проблемы с распределением массива структур - PullRequest
0 голосов
/ 11 мая 2019

Мой код происходит сбой каждый раз, когда я пытаюсь получить доступ к элементам данных Structs.Это должно быть потому, что он не распределен должным образом.Я не знаю, почему это не работает.Структура выглядит так, как будто она определена правильно.Похоже, что malloc настроен правильно.Я использую правильный формат для доступа к данным.Однако, когда я пытаюсь получить доступ к чему-либо, происходит просто ошибка.

struct fracBlock {
  struct fracBlock *next ;
  fraction frac ;
} ;

static struct fracBlock *fbp ;

void init_heap(void){ fbp = NULL ; }

fraction *new_frac(void){
  struct fracBlock **tempBlock ;
  struct fracBlock *prev ;
  struct fracBlock *curr ;
  fraction *tempFrac ;
  fraction testFrac ;
  int i ;
//if free list is empty malloc 10 blocks
  if ( fbp == NULL ){
    tempBlock = ( struct fracBlock** )malloc(10*sizeof(struct fracBlock)) ;

  //if no more space left
  if ( tempBlock == NULL ) {
    printf( "\nError: No more memory space left for allocation!\n" ) ;
    exit(1) ;
  }

  tempBlock[0]->next = tempBlock[1] ;
  tempBlock[1]->next = tempBlock[2] ;
  tempBlock[2]->next = tempBlock[3] ;
  tempBlock[3]->next = tempBlock[4] ;
  tempBlock[4]->next = tempBlock[5] ;
  tempBlock[5]->next = tempBlock[6] ;
  tempBlock[6]->next = tempBlock[7] ;
  tempBlock[7]->next = tempBlock[8] ;
  tempBlock[8]->next = NULL ;
  *tempFrac = tempBlock[9]->frac ;

  return tempFrac ;
}

Ответы [ 2 ]

3 голосов
/ 11 мая 2019

У вас есть ряд серьезных ошибок в размещенном коде.

1) Отсутствует }

2) tempfrac - это указатель неинициализированный , но вы делаете *tempfrac = ... Это неопределенное поведение, поэтому может произойти что угодно. Авария вероятна. Может быть, вы забыли malloc память как tempfrac = malloc(sizeof *tempfrac);

3) Даже если tempfrac назначено с помощью malloc, строка *tempFrac = tempBlock[9]->frac ; все еще неверна, поскольку frac в блоке 9 также не инициализирована. Код не имеет смысла .. он пытается вернуть (указатель на) неинициализированное значение.

4) Использование двойного указателя просто неправильно. Код должен быть больше похож на:

  struct fracBlock *tempBlock ;  // Single *

  if ( fbp == NULL ){
    tempBlock = malloc(10*sizeof *tempBlock) ;

    //if no more space left
    if ( tempBlock == NULL ) {
      printf( "\nError: No more memory space left for allocation!\n" ) ;
      exit(1) ;
    }

    tempBlock[0].next = tempBlock + 1; // or tempBlock[0].next = &tempBlock[1];
    tempBlock[1].next = tempBlock + 2;
    ...

5) Вы никогда не обновите fbp Другими словами, malloc, который вы делаете, превращается в указатель, который выходит из области видимости после завершения функции. Итак, у вас есть утечка памяти. Скорее всего, вам не следует использовать локальную переменную tempBlock, а работать непосредственно с fbp. Как:

  if ( fbp == NULL ){
    fbp = malloc(10*sizeof *fbp) ;

    //if no more space left
    if ( fbp == NULL ) {
      printf( "\nError: No more memory space left for allocation!\n" ) ;
      exit(1) ;
    }

    fbp[0].next = fbp + 1;
    fbp[1].next = fbp + 2;
    ...

Тем не менее, обратите внимание, что глобальные переменные почти всегда плохи. Избегайте их.

0 голосов
/ 11 мая 2019

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

Если у меня есть целочисленный массив, я выделяю его следующим образом:

int * x ; // Array of length 3
x = ( int * ) malloc( 3 * sizeof( int ) ) ;

Я приведу x как int *, потому что malloc вернет адрес в куче, и я хочу, чтобы этот адрес интерпретировался как указатель на целое число. Однако я использую int внутри вызова malloc, поскольку хочу выделить достаточно места для 3 int типов.

Итак, вы захотите использовать sizeof( struct fracBlock * ) вместо sizeof( struct fracBlock ) по этой причине. Вам также необходимо выделить место для каждого элемента этого массива с помощью вызовов malloc. Это связано с тем, что каждый элемент массива является указателем, и когда вы выделяете его, он не обязательно обязательно указывает на любое пространство, которое вы уже выделили.

Кроме того, я думаю, вам нужно выделить место для tempFrac с помощью другого вызова malloc. Вы разыменовываете указатель при назначении ему значения, но пространство кучи не было выделено, что приводит к segfault, поскольку вы не обязательно имеете разрешение на запись в эту память.

Реальное решение, хотя ... сборка мусора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...