Ошибка сегментации в программе c, используйте malloc (Linux OS) - PullRequest
0 голосов
/ 28 апреля 2019

эта программа работает в Windows, но получает "Ошибка сегментации (дамп ядра)" в Linux.Я догадываюсь об указателях ошибок или функции malloc. Я не могу вернуть массив массивов без указателей и malloc.

struct team {
    char name[12];
    int m_count;
    int score;
};

struct team *teamName(){        

    FILE *fp;
    fp=fopen("teams.txt", "r");

    struct team *items; 
    items= (struct team *) malloc(sizeof(struct team) * 10);

    int i;
    for(i=0; i<10; i++)
    {
        fscanf(fp, "%s\n" , items[i].name); 
    }

    fclose(fp);
    return items;
}

int main(void)
{   struct team *items = teamName();    
    getMatch(items);
}

1 Ответ

1 голос
/ 28 апреля 2019

В вашем коде несколько проблем:

  • вы не проверяете fopen успех

  • вы не проверяете fscanf success, и если имя чтения больше 11, вы записываете из буфера с неопределенным поведением

  • почему \n в формате fscanf ?

  • если вы прочитаете менее 10 имен, некоторые записи не будут установлены, с риском последующего неопределенного поведения


Предложение, учитывающее мои замечания, может быть:

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

struct team {
  char name[12];
  int m_count;
  int score;
};

struct team *teamName(){        
  FILE *fp = fopen("teams.txt", "r");

  if (fp == NULL)
    return NULL;

  struct team *items = malloc(sizeof(struct team) * 10);

  int i;

  for (i=0; i<10; i++)
  {
    if (fscanf(fp, "%11s" , items[i].name) != 1) {
      /* empty other names */
      do {
        items[i].name[0] = 0;
      }
      while (++i != 10);
      break;
    }
  }

  fclose(fp);
  return items;
}

int main(void)
{
  struct team *items = teamName();

  if (items != NULL) {
    for (int i = 0; i != 10; ++i) {
      if (items[i].name[0] != 0)
        puts(items[i].name);
    }
  }

  /* getMatch(items); */
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall m.c
pi@raspberrypi:/tmp $ cat teams.txt 
aze qsd
loop
bar
pi@raspberrypi:/tmp $ ./a.out
aze
qsd
loop
bar
pi@raspberrypi:/tmp $ 

Обратите внимание, что fscanf читает слова, я имею в виду, что имя не должно содержать пробела, иначе вам нужно использовать, например, fgets

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