#c #struct #mingw #function-pointers
#c #структура #mingw #указатели на функции
Вопрос:
Я пытаюсь печатать время, используя указатели на функции и структуры. Это не дает никакой ошибки. Сначала это работает, но позже «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(amp;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("nn 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)
функцией.
Комментарии:
1. Выглядит нормально. Вероятно, проблема в несвязанной части кода. попробуйте valgrind (если предупреждения ничего не показывают).
2. Не скрывайте природу указателя за typedefs (
Random
,Randomness
) . Это почти всегда затрудняет чтение и поддержку вашего кода. (И пример кода не является исключением.)3. Вы никогда не инициализируете указатели на функции…
Ответ №1:
Вы должны назначить указатели на функции полям-членам в структуре:
Random CreateRandom(){
Random this;
this = (Random) malloc(sizeof(struct RANDOM));
this->date = BringTime();
// assign function pointer to actual functions
this->Date = amp;DateOfNow;
this->Write = amp;WriteDate;
return this;
}
Конечно, прототипы DateOfNow
и WriteDate
должны быть доступны до CreateRandom
определения.
Примечание: вы можете написать this->Date = DateOfNow;
(без amp;
as amp;
с идентификатором функции является излишним).
Ответ №2:
Ваша функция create является неполной:
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*
функции как своего рода конструктор, вы также должны правильно установить указатели на функции.