Как использовать указатели на функции в C, используя структуры? - PullRequest
0 голосов
/ 12 апреля 2019

Я пытаюсь распечатать время, используя указатели функций и структуры. Это не дает никакой ошибки. Сначала он работает, но позже «Test.exe перестал работать!».

Мои файлы: Random.c Random.h, Randomness.c Randomness.h, Test.c

Random.h

struct RANDOM {
    char* date;
    char* (*Date) (struct RANDOM*);
    void (*Write) (struct RANDOM*);
};
typedef struct RANDOM* Random;

Random CreateRandom();
char* DateOfNow(const Random);
void WriteDate(const Random);

Random.c

char* BringTime(){
    char* buff = malloc(sizeof(char)*100);
    time_t now = time(0);
    strftime(buff, 100, "%Y-%m-%d %H:%M",localtime(&now));

    return buff;
}

Random CreateRandom(){
    Random this;
    this = (Random) malloc(sizeof(struct RANDOM));  
    this->date = BringTime();

    return this;
}

char* DateOfNow(const Random this){
     return this->date;
}

void WriteDate(const Random this){
    printf("\n\n Date is: %s", this->date);
}

Randomness.h

struct RANDOMNESS{
    Random super;
};

typedef struct RANDOMNESS* Randomness;

Randomness CreateRandomness();

Randomness.c

Randomness CreateRandomness(){
    Randomness this;
    this = (Randomness)malloc(sizeof(struct RANDOMNESS));
    this->super = CreateRandom();

    return this;
}

test.c

int main() {

    Randomness rnd = CreateRandomness();
    printf("works till here");
    rnd->super->Write(rnd->super);
}

Вывод: работает до сих пор

После этого вывода он перестает работать «Test.exe остановлен».

Я пытался printf("%p", rnd->super) Он дал мне адрес. Так что, возможно, есть проблема с функцией Write(rnd->super).

Ответы [ 2 ]

0 голосов
/ 12 апреля 2019

Ваша функция создания не завершена:

Random CreateRandom(){
    Random this;
    this = (Random) malloc(sizeof(struct RANDOM));  
    // Content of the memory is undefined!
    this->date = BringTime();
    // What about Write() and Date()? <<<======= ERROR IS HERE
    return this;
}

...

Randomness CreateRandomness(){
    Randomness this;
    this = (Randomness)malloc(sizeof(struct RANDOMNESS));
    this->super = CreateRandom();

    return this;
}

...

int main() {

    Randomness rnd = CreateRandomness();
    printf("works till here");
    rnd->super->Write(rnd->super); // << using unspecified values is undefined behaviour.
}

Вы присваиваете некоторое значение date, но не Date и Write. Это означает, что у вас есть какое-то полезное значение в rnd->super, но содержимое rnd->super->Write не определено.

Если вы хотите использовать функции Create* в качестве конструктора, вы также должны правильно установить указатели функций.

0 голосов
/ 12 апреля 2019

Вы должны назначить указатели функций для полей элементов в структуре:

Random CreateRandom(){
    Random this;
    this = (Random) malloc(sizeof(struct RANDOM));  
    this->date = BringTime();
    // assign function pointer to actual functions
    this->Date = &DateOfNow; 
    this->Write = &WriteDate;

    return this;
}

Конечно, прототипы DateOfNow и WriteDate должны быть доступны до определения CreateRandom.

Примечание: вы можете написать this->Date = DateOfNow; (без & как & с идентификатором функции - излишек).

...