2016-12-11 6 views
1

Мой код продолжает сбой при выполнении *arr = malloc(i * sizeof(struct cluster_t*));. Кластер - это структура. Я не уверен, в чем проблема. Второй вход представляет собой массив структур (кластеров) Предполагается, чтобы загрузить текстовый файл в массив, каждая строка в виде отдельной структуры первый вход является .txt файл, содержащий этот:Сбой программы при выполнении malloc

count=20 
40 86 663 
43 747 938 
47 285 973 
49 548 422 
52 741 541 
56 44 854 
57 795 59 
61 267 375 
62 85 874 
66 125 211 
68 80 770 
72 277 272 
74 222 444 
75 28 603 
79 926 463 
83 603 68 
86 238 650 
87 149 304 
89 749 190 
93 944 835 

Здесь часть кода, который, кажется, вышел из строя (я изменил его немного после первого ответа) Это не полный код:

int load_clusters(char *filename, struct cluster_t **arr) //nefunkcne 
{ 
    assert(arr != NULL); 

    char buffer_load[256] = {'0'}; 
    int riadok = 0; 
    int count = 0; 

    int *X = malloc(sizeof(int)); 
    if (X == NULL) { 
     perror("Chyba mallocu na load_clusters X"); 
     free(X); 
     exit(EXIT_FAILURE); 
    } 

    int *Y = malloc(sizeof(int)); 
    if (Y == NULL) { 
     perror("Chyba mallocu load_clusters Y"); 
     free(X); 
     free(Y); 
     exit(EXIT_FAILURE); 
    } 

    int *ID = malloc(sizeof(int)); 
    if (ID == NULL) { 
     perror("Chyba mallocu v load_clusters ID"); 
     free(X); 
     free(Y); 
     free(ID); 
     exit(EXIT_FAILURE); 
    } 

    FILE *subor = fopen(filename, "r"); 
    if (subor == NULL) { 
     perror("Chyba nacitania suobru fopen load_clusters!"); 
    } 

    while (fgets(buffer_load, sizeof buffer_load, subor) != NULL) { 
     if (riadok > 0) { 
      struct cluster_t shluk; 
      sscanf(buffer_load,"%d %d %d", ID, X, Y); 
      init_cluster(&shluk, 1); 
      struct obj_t objekt; 
      objekt.id = *ID; 
      objekt.x = *X; 
      objekt.y = *Y; 

      append_cluster(&shluk, objekt); 

      arr[riadok - 1] = malloc(sizeof(struct cluster_t*)); 
      if (arr[riadok-1] == NULL) { 
       perror("Chyba mallocu v load_clusters 388!"); 
       free(arr[riadok - 1]); 
       exit(EXIT_FAILURE); 
      } 

      (*arr)[riadok - 1] = shluk; 
     } else { 
      sscanf(buffer_load, "count=%d", &count); 
      *arr = malloc(count * sizeof(struct cluster_t)); 
      if (arr == NULL) { 
       perror("Chyba mallocu v load_clusters 400!"); 
       free(*arr); 
       exit(EXIT_FAILURE); 
      } 
     } 
     riadok++; 
    } 

    fclose(subor); 
    free(X); 
    free(Y); 
    free(ID); 
    return cout; 
} 

Полный код я в курсе (не забудьте использовать `-std = c99 - Wextra -Wall -Werror -DNDEBUG, а также -lm, если в gcc из-за математической библиотеки): https://docs.google.com/document/d/1xoNcBpY1lkmki3-E5WUYFVg-xojjvEkUJ63XC_UzhtM/edit?usp=sharing

+0

Комментарии не для широкого обсуждения; этот разговор был [перемещен в чат] (http://chat.stackoverflow.com/rooms/130349/discussion-on-question-by-luk164-program-crashes-when-malloc-executed). –

+0

всегда хорошо, чтобы показать, что из указанных структур –

ответ

0

следующий код полностью компилируется, но не будет связываться из-за отсутствия вспомогательных функций.

Предостережение: я не могу проверить код, поэтому не уверен, что он будет работать должным образом.

#include <stdio.h> // fopen(), fclose(), fgets() 
#include <stdlib.h> // exit(), EXIT_FAILURE, malloc() 
#include <assert.h> // assert() 
#include <string.h> // strchr() 

struct cluster_t 
{ 
}; 

struct obj_t 
{ 
    int id; 
    int x; 
    int y; 
}; 

void init_cluster(struct cluster_t*, int); 
void append_cluster(struct cluster_t*, struct obj_t*); 

int load_clusters(char *filename, struct cluster_t **arr) //nefunkcne 
{ 
    assert(arr != NULL); 

    char buffer_load[256] = {'0'}; 
    int riadok = 0; 
    int i = 0; 

    int X; 
    int Y; 
    int ID; 

    FILE *subor = NULL; 
    if(NULL == (subor = fopen(filename, "r"))) 
    { 
     perror("Chyba nacitania suobru fopen load_clusters!"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, fopen successful 

    // initialize for number of struct instances 
    if(! fgets(buffer_load, sizeof(buffer_load), subor)) 
    { 
     fprintf(stderr, "unable to read first line from input file\n"); 
     exit(EXIT_FAILURE); 
    } 

    char *token = NULL; 
    if(NULL == (token = strchr(buffer_load, '='))) 
    { 
     fclose(subor); 
     exit(EXIT_FAILURE); 
    } 

    else 
    { // else delimeter found 
     token++; // step past '=' 
     i = atoi(token); 

     // allocate array of pointers to 'struct cluster_t' 
     if(NULL == (*arr = malloc((size_t)i * sizeof(struct cluster_t*)))) 
     { 
      perror("Chyba mallocu v load_clusters 400!"); 
      fclose(subor); 
      exit(EXIT_FAILURE); 
     } 

     // implied else, malloc successful 
    } 


    while(riadok < i && fgets(buffer_load, sizeof buffer_load, subor)) 
    { 
     struct cluster_t shluk; 
     sscanf(buffer_load,"%d %d %d", &ID, &X, &Y); 

     init_cluster(&shluk, 1); 

     struct obj_t objekt; 
     objekt.id = ID; 
     objekt.x = X; 
     objekt.y = Y; 
     append_cluster(&shluk, &objekt); 

     if(NULL == (arr[riadok] = malloc(sizeof(struct cluster_t)))) 
     { 
      perror("Chyba mallocu v load_clusters 388!"); 
      fclose(subor); 

      for(int j=0; j<riadok; j++) 
      { 
       free(arr[j]); 
      } 

      exit(EXIT_FAILURE); 
     } 

     memcpy(arr[riadok], &shluk, sizeof(struct cluster_t)); 

     riadok++; 
    } 

    fclose(subor); 

    return i; 
} 
+0

Я разместил полный код, а также пользовательские настройки для gcc. – Luk164

0

Ваш код слишком сложен и имеет проблемы:

  • Вам не нужно выделять данные передавать указатели scanf(), просто передать адреса локальных переменных.
  • Проверьте возвращаемое значение scanf(): оно возвращает количество успешных конверсий. Если преобразование завершилось неудачно, соответствующая переменная не будет установлена, и остальные конверсии тоже не сработают.
  • Если ваш файл txt начинается с пробелов, таких как count=20, формат scanf должен содержать начальное пространство для использования в этих пространствах: " count=%d".
  • Кажется, что существует много путаницы между указателями и структурами: должна ли функция выделять массив кластеров или загружать последовательность объектов в выделенный кластер?

Вот упрощенная версия, которая загружает объекты в единый выделенный кластер:

int load_clusters(const char *filename, struct cluster_t **arr) { 
    char buffer_load[256]; 
    int riadok, count, X, Y, ID; 
    struct cluster_t *cp; 

    assert(arr != NULL); 

    // Open the input file 
    FILE *subor = fopen(filename, "r"); 
    if (subor == NULL) { 
     perror("Chyba nacitania suobru fopen load_clusters!"); 
     exit(EXIT_FAILURE); 
    } 

    // Read and parse the count line 
    if (fgets(buffer_load, sizeof buffer_load, subor) == NULL || 
     sscanf(buffer_load, " count=%d", &count) != 1) { 
     perror("missing count line in file\n"); 
     fclose(subor); 
     exit(EXIT_FAILURE); 
    } 

    // allocate and initialize the cluster 
    *arr = cp = malloc(sizeof(**arr)); 
    if (cp == NULL) { 
     perror("Chyba mallocu v load_clusters 400!"); 
     exit(EXIT_FAILURE); 
    } 
    init_cluster(cp, count); 

    riadok = 0; 
    while (riadok < count && 
      fgets(buffer_load, sizeof buffer_load, subor) != NULL) { 
     if (sscanf(buffer_load,"%d %d %d", &ID, &X, &Y) == 3) { 
      struct obj_t objekt; 
      objekt.id = ID; 
      objekt.x = X; 
      objekt.y = Y; 
      append_cluster(cp, objekt); 
      riadok++; 
     } 
    } 

    fclose(subor); 
    return riadok; 
}