C — «ошибка: Не удается получить доступ к памяти по адресу» происходит

#c

Вопрос:

 #include <stdio.h>
#include <string.h>

typedef struct birth{
    char *name;
    char time[12];

}birth;

void swap(struct birth *a, struct birth *b){
    struct birth tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

int main(){
    int n;
    birth list[100], *p, *q;

    scanf("%d", amp;n);
    getchar();

    for(p = list; p < list   n; p  ){
        scanf("%s %s", amp;p->name, amp;p->time);
    }

    for(p = list; p < list   n - 1; p  ){
        for(q = p   1; q < list   n; q  ){
            if(strcmp(p->time, q->time) > 0){
                swap(p ,q);
            }
            else if(strcmp(p->time, q->time) == 0){
                if(strcmp(p->name, q->name) > 0){
                    swap(p ,q);
                }
            }
        }
    }

    for(int i = 0; i < n; i  ){
        printf("%s %sn", list[i].name, list[i].time);
    }

    

    return 0;
}
 

Я решаю проблему получения n, что означает количество студентов, повторяю количество студентов, получаю имя и дату рождения студента и заранее печатаю имена, если дата рождения совпадает.
Однако ответа не последовало, поэтому я проверил с помощью отладчика в vcode, и когда я получил ввод, дата рождения была хорошо введена, но имени не было.

Комментарии:

1. Пожалуйста, не помечайте C , если ваш вопрос касается только C

2. scanf("%s %s", amp;p->name, amp;p->time); Вы никогда не выделяете никакого места для name .

3. Кроме того, приоритет оператора означает, что amp;p->name это эквивалентно amp;(p->name) . Как p->name уже char * сказано, это дает a char ** , который будет генерировать предупреждения в вашем компиляторе при передаче в качестве аргумента scanf . Вы можете просто пройти p->name и p->time прямо туда scanf .

Ответ №1:

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

 typedef struct birth{
    char *name;
    char time[12];
}birth;
...
scanf("%s %s", amp;p->name, amp;p->time); // error, amp;p->name points to nowhere
 

Вы должны либо выделить память самостоятельно, либо объявить ее как массив символов фиксированного размера. Было бы лучше также проверить границы строк:

 #define S_NAME 12
#define S_TIME 12

typedef struct birth{
    char name[S_NAME];
    char time[S_TIME];
}birth;

...
// read string with safety guard
if (fgets(p->name, S_NAME, stdin) != NULL) {
    // read name successfully
}

if (fgets(p->time, S_TIME, stdin) != NULL) {
    // read time successfully
}