C динамический массив структур, без ошибок, программа завершается при запуске - PullRequest
0 голосов
/ 09 октября 2018

При запуске программа немедленно завершает работу из-за проблемы, которая, по моему мнению, связана с выделением памяти.Основная функция вызывает только эту функцию, а другую функцию, чтобы удалить выделенную память

DrinkMachine *create(void){
    FILE *inFile;
    //Pointer to data structure
    DrinkMachine *drinkMachine;
    // Memory allocation
    drinkMachine = calloc(1, sizeof(DrinkMachine));
    if(drinkMachine == NULL)    // Check success
        return NULL;

    // Open the input file for reading
    inFile = fopen("drink_machine.txt" , "r");
    if(!inFile){
        puts("Error opening file");
        return NULL;
    }
    // Read drink count from file
    fscanf(inFile, "%d", &(drinkMachine->numItems));
    printf("DEBUG read file arrayLen: %d\n", drinkMachine->numItems);

    // Dynamically create array of drink item structures 

    drinkMachine->drinkItem = malloc(drinkMachine->numItems*sizeof(DrinkItem));
    if(drinkMachine->drinkItem == NULL){
        puts("ERROR: Failed to allocate memory");
        return NULL;
    }

    // Put information from file into drinkItem structs
    for(int i=0; i < drinkMachine->numItems; ++i){
        fscanf(inFile, "%s %lf %d", (drinkMachine->drinkItem[i].name), &(drinkMachine->drinkItem[i].price), &(drinkMachine->drinkItem[i].drinkLeft));
        printf("DEBUG drink %d is: %s   %lf   %d\n", i, (drinkMachine->drinkItem[i].name), (drinkMachine->drinkItem[i].price), (drinkMachine->drinkItem[i].drinkLeft));
    }

    // Close inFile
    fclose(inFile);

    // Force output to screen
    puts("DEBUG readFile Success!");
    fflush(stdout);

    return drinkMachine;
}

Программа столкнулась с ошибками или неправильно распределит память и будет успешно выводить сообщение об ошибке при запуске, пока я не вставлюстрока:

drinkMachine->drinkItem = malloc(drinkMachine->numItems*sizeof(DrinkItem));

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

typedef struct _DrinkItem{
    int id;
    char *name;
    double price;
    int drinkLeft;
    int drinkSold;
} DrinkItem;

typedef struct _DrinkMachine{
    int version;
    int numItems;
    int  drinkLocation;
    DrinkItem *drinkItem;
} DrinkMachine;

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

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

Вот предложение кода, которое, я думаю, исправит все ваши ошибки (не проверял его, поскольку вы не приводили пример ввода и вывода):

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

typedef struct DrinkItem {
  int id;
  char *name;
  double price;
  int drinkLeft;
  int drinkSold;
} DrinkItem;

typedef struct DrinkItem {
  int version;
  size_t numItems;
  int drinkLocation;
  DrinkItem *drinkItems;
} DrinkMachine;

static void helper_free(DrinkItem *drinkItems, size_t n) {
  for (size_t i = 0; i < n; i++) {
    free(drinkItems[i].name);
  }
  free(drinkItems);
}

DrinkMachine *create(char const *path) {
  FILE *inFile = fopen(path, "r");
  if (!inFile) {
    fprintf(stderr, "Error opening file");
    return NULL;
  }

  size_t numItems;
  if (fscanf(inFile, "%zu", &numItems) != 1) {
    fprintf(stderr, "Error parsing\n");
    return NULL;
  }
#ifndef NDEBUG
  printf("DEBUG read file arrayLen: %zu\n", numItems);
#endif

  DrinkItem *drinkItems = malloc(numItems * sizeof *drinkItems);
  if (!drinkItems) {
    fprintf(stderr, "ERROR: Failed to allocate memory");
    return NULL;
  }
  for (size_t i = 0; i < numItems; ++i) {
    char *name = malloc(100);
    if (!name) {
      helper_free(drinkItems, i);
      fprintf(stderr, "ERROR: Failed to allocate memory");
      return NULL;
    }
    double price;
    int drinkLeft;
    if (fscanf(inFile, "%99s %lf %d", name, &price, &drinkLeft) != 3) {
      free(name);
      helper_free(drinkItems, i);
      fprintf(stderr, "Error parsing\n");
      return NULL;
    }
    drinkItems[i] =
        (DrinkItem){.name = name, .price = price, .drinkLeft = drinkLeft};

#ifndef NDEBUG
    printf("DEBUG drink %zu is: %s   %lf   %d\n", i, name, price, drinkLeft);
#endif
  }

  fclose(inFile);

  DrinkMachine *drinkMachine = malloc(sizeof *drinkMachine);
  if (!drinkMachine) {
    helper_free(drinkItems, numItems);
    fprintf(stderr, "ERROR: Failed to allocate memory");
    return NULL;
  }
  *drinkMachine =
      (DrinkMachine){.drinkItems = drinkItems, .numItems = numItems};

#ifndef NDEBUG
  puts("DEBUG readFile Success!\n");
#endif

  return drinkMachine;
}
0 голосов
/ 09 октября 2018

Вы должны выделить память для каждого имени тоже.Вы читаете символы в нераспределенный указатель в строке 30. Вы должны прочитать имя во временный массив, получить длину имени, выделить (длина + 1) байтов памяти для имени и обработать данные.

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