C массив структуры (исключение выдается) - PullRequest
1 голос
/ 15 апреля 2019

Я создал массив структуры Human, который состоит из char *name.

Я использую такую ​​функцию:

Human *createHuman(char *name){
    Human *h = malloc(sizeof(Human));
    h->name = strdup(name);
    return h;
}

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

void gen_Humans(Human array[MAX], int n){
    //n == max;
    for (int i = 0; i<n; i++){
        char *name = gen_name_function_used_before_WORKING();
        array[i] = *createHuman(*name);
    }
    …
}

Как я уже сказал, если я создаю одного человека, он работает просто отлично. Я отладил свой код, и когда я добрался до точки strdup(name), он бросил мне это:

my error: Exception thrown at 0x53DCF6E0 (ucrtbased.dll) in project.exe:
0xC0000005: Access violation reading location 0x00000070.

Я использую VS 2017 Enterprise.

Ответы [ 2 ]

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

Добавление к ответу @ MortizSchmidt:

  • Вы не проверяете результаты malloc(). Вы должны сделать это, даже если шансы на неудачу невелики.
  • Вы теряете память - так как вы никогда не освобождаете память malloc() и нигде не держите указатель. Помните, что C не похож на Java - назначение не является назначением ссылки.
  • Обратите внимание, что индикатор MAX в сигнатуре функции не оказывает никакого влияния. Параметр - это int * любой способ, которым вы пишете: int* array, int array[] или int array[MAX].

На самом деле, зачем выделять структуру Человека, а не просто место для строки?

struct Human createHuman(char *name){
    if (name == NULL) {
        struct Human h = { NULL };
        return h;
    }
    struct Human h = { strdup(name) };
    if (h.name == NULL) { /* handle error here */ }
    return h;
}

void gen_Humans(Human array[MAX], int n){
    for (int i = 0; i < n; i++) {
        char *name = gen_name_function_used_before_WORKING();
        array[i] = createHuman(name);
    }
    …
}

Это имеет дополнительное преимущество инициализации всех полей в Human после name до 0.

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

При вызове вашей функции createHuman вы передаете значение вашего имени:

array[i] = *createHuman(*name);

При создании этого приложения Iam получает следующее предупреждение компилятора (GCC):

warning: passing argument 1 of 'createHuman' makes pointer from integer without a cast

, так как ваша функция createHuman ожидает адрес имени, вы также должны передать адрес. Например:

array[i] = *createHuman(name);
...