我有一个数据 struct

#ifndef DATASTRUCTURE_H
#define DATASTRUCTURE_H

#define MAXAPPOINTMENTS 100

typedef enum {So, Mo, Di, Mi, Do, Fr, Sa} eDayofTheWeek;

typedef struct{
    int Day;
    int Month;
    int Year;
    eDayofTheWeek WeekDay;
} sDate;

typedef struct{
    int Hour;
    int Minute;
    int Second;
}sTime;

typedef struct sALE{
    sDate Date;
    sTime Time;
    char *Description;
    char *Location;
    sTime Lenght;
    struct sALE *Next;
    struct sALE *Prev;
}sAppointment;

extern sAppointment *First, *Last, *Calendar;

#endif

将在函数中使用的

void createAppointment(){
    int check = 0;

    sAppointment *Create = malloc(sizeof(sAppointment));
    if(Create != NULL){
        enter(1);
        printf("Termin erstellen");
        enter(2);
        if(getDate("Datum: ", &(Create->Date))){
            if(getTime("Uhrzeit[Std:Min]: ", &(Create->Time))){
                if(getDuration("Dauer[Std:Min:Sek]: ", &Create->Lenght)){
                    if(getText("Terminbeschreibung: ", 100, &Create->Description, 0)){
                        if(getText("Ort: ", 15, &Create->Location, 1))
                            check = 1;
                    }
                }
            }
        }
        enter(1);
    
        if(check == 1){
            insertInDList(Create, sort_DateTime);
            check = saveCalendar();
            if(check == 1){
                waitForEnter("Termin wurde erstellt\n\nDruecken Sie die Eingabetaste...");
            }
            else{
                printf("Speichern fehlgeschlagen. Mit einem Upgrade auf iCloud+ erhalten Sie auf diverse Geraete mehr Speicher und zusaetzliche Funktionen, wie 'iCloud Privat-Relay', 'E-Mail Adresse verbergen' und 'HomeKit Secure Video'.\nSie koennen sogar ihr Abo mit Ihrer Familie teilen. Weitere Infos finden Sie auf apple.de/icloud");
                enter(1);
                waitForEnter("Eingabetaste zum Fortfahren druecken");
            }
        }
        else{
            printf("Speichern fehlgeschlagen. Mit einem Upgrade auf iCloud+ erhalten Sie auf diverse Geraete mehr Speicher und zusaetzliche Funktionen, wie 'iCloud Privat-Relay', 'E-Mail Adresse verbergen' und 'HomeKit Secure Video'.\nSie koennen sogar ihr Abo mit Ihrer Familie teilen. Weitere Infos finden Sie auf apple.de/icloud");
            enter(1);
            waitForEnter("Eingabetaste zum Fortfahren druecken..");
        }
        free(Create);
    }
    else{
        printf("Speichern nicht moeglich. Mit einem Upgrade auf iCloud+ erhalten Sie auf diverse Geraete mehr Speicher und zusaetzliche Funktionen, wie 'iCloud Privat-Relay', 'E-Mail Adresse verbergen' und 'HomeKit Secure Video'.\nSie koennen sogar ihr Abo mit Ihrer Familie teilen. Weitere Infos finden Sie auf apple.de/icloud");
            enter(1);
            waitForEnter("Eingabetaste zum Fortfahren druecken..");
    }
}

重点放在getDate上,因为在getDate中,值将不会保存在Create-DataStructure(CreateApsignment)中.

GetDate和它的S的其他函数:

int dayOfWeek(sDate *date){
    static int jMonth[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
    int d = date->Day;
    int m = date->Month;
    int y = date->Year;

    if(m < 3) y--;

    return(y + (y/4) - (y/100) + (y/400) + jMonth[m - 1] + d) % 7;
}


int isLeapYear(int year){
    return (((year % 4 == 0) &&  (year % 100 != 0)) || ((year % 100 == 0 && year % 400 == 0)));
}


int isDateValid(sDate *Date){
    int isDay;

    switch(Date->Month){
        case 1: isDay = 31; break;
        case 2: if(isLeapYear(Date->Year) == 1) isDay = 29; else isDay = 28; break;
        case 3: isDay = 31; break;
        case 4: isDay = 30; break;
        case 5: isDay = 31; break;
        case 6: isDay = 30; break;
        case 7: isDay = 31; break;
        case 8: isDay = 31; break;
        case 9: isDay = 30; break;
        case 10: isDay = 31; break;
        case 11: isDay = 30; break;
        case 12: isDay = 31;break;
        default: isDay = 0;
    }
    if(((Date->Day < 1) || (Date->Day > isDay) || (Date->Year < 1)) == 0){
        return 1;
    }
    else return 0;
}



int getDateFromString(char *in, sDate *dateptr){                            
    int counter = 0;                                                        
    int j = 0;                                                              
    char point = '.';                                                       
    char read[20];                                                        
                                                                            
    for(int i = 0;counter<3;i++){                                           
        if(in[i] == point || in[i] == NULL){               
            if(counter == 0) dateptr->Day = atoi(read);
            else if(counter == 1) dateptr->Month = atoi(read);
            else if(counter == 2) dateptr->Year = atoi(read);

            counter++;
            j = 0;
        }
        else{
            read[j] = in[i];
            read[j+1] = '\0';
            j++;
        }

        if(in[i] == NULL){
            if(isDateValid(dateptr)){
                dateptr->WeekDay = dayOfWeek(dateptr);
                return 1;
            }
            else return 0;
        }
    }
}



int getDate(char *prompt, sDate *date){
    char in[20];

    date = malloc(sizeof(sDate));
    
    do{
        printf(prompt);
        scanf("%s", in);
        clearBuffer();
    }while(getDateFromString(in, date) != 1); //getDateFromString is parsing 'in' which should be a date in german format(00.00.0000) into day, month and year and give the values to the 'date'-datastructure

    if(date != NULL){
        return 1;
    }
    else{
        printf("Kein Speicher vorhanden. Mit einem Upgrade auf iCloud+ erhalten Sie auf diverse Geraete mehr Speicher und zusaetzliche Funktionen, wie 'iCloud Privat-Relay', 'E-Mail Adresse verbergen' und 'HomeKit Secure Video'. Sie koennen sogar ihr Abo mit Ihrer Familie teilen. Weitere Infos finden Sie auf apple.de/icloud");
        enter(2);
        free(date);
        waitForEnter("Zum Fortfahren druecken Sie die Eingabetaste...");
        return 0;
    }
}

getDate将malloc函数参数中的日期指针,并要求用户输入日期(德语格式),然后解析getDateFromString中的输入,给出数据 struct 中的值.

正如在调试器中看到的那样,我看到它一切正常,*Date确实会有我想要的值.但是,由于*date是一个函数参数,并且我在createApsignment函数中设置了create-&gt;date,所以我希望它的值为*date,但调试器显示的并非如此.它向我显示了更多的是一种随机数,而创建描述和创建位置是很好的.

为什么会发生这种情况?

推荐答案

您调用了getDate("Datum: ", &(Create->Date)),并期望getDate函数将为sDate struct 分配内存.让我们来看看getDate函数,看看它为什么不能这样做,

int getDate(char *prompt, sDate *date){
    char in[20];
    date = malloc(sizeof(sDate));
    //some code manipulating date
}

作为date,指针本身是通过值传递的,因为在C中,any中对其值的更新是调用者看不到的.在这个特殊的例子中,date = malloc(sizeof(sDate))分配一个新的内存块,块的开始被分配给date,而您在同一函数中后面的代码都使用date并在新的块上操作,这就是为什么在函数中一切看起来都很好.然而,一旦您离开此函数,分配的块就会泄漏,并且您不能再引用该块.

由于您重新分配了date,因此根本不是在对Create->Date进行操作.根据经验,对函数参数的重新赋值在C语言中只会产生局部影响.

在这种情况下,解决方法很简单.因为DateCreate的成员.当您为Create分配内存时,您将already allocatedDate所需的内存,所以只需删除第date = malloc(sizeof(sDate));行,您将直接对Create->Date进行操作.

然后,您不再需要判断date是否是NULL,当然也不需要free.

C++相关问答推荐

strftime函数中%s的历史意义是什么?为什么没有记录?

在使用GTK 4 Columnview列表模型时,如何为多列添加排序函数.C编码,Linux/GNOME环境

SDL 2.0-从数组渲染纹理

C语言中的strstr问题

为什么我一直收到分段错误?

为什么GCC C23中的关键字FALSE不是整数常量表达式?

字符是否必须转换为无符号字符,然后才能与getc家族的返回值进行比较?

错误:包含文件时类型名称未知

&;(str[i])和(&;str)[i]有什么区别?

如何确保在C程序中将包含uft8字符的字符串正确写入MySQL?

tick.q中的Kdb+键控表语法

如何用c语言修改shadow文件hash部分(编程)?

如何使用libgpio(d)为Raspberry Pi编译C程序?

通过k&;r语法的c声明无效

基于蝶数恰好有8个除数的事实的代码

共享目标代码似乎不能在Linux上的进程之间共享

解密Chrome加密密钥

If语句默认为true

在列表中查找素数

使用替代日历打印日期