В моем проекте все сильно упрощено, поэтому, например, здесь в структуре только один int.
В .ч :
typedef struct
{
int id;
}Jeux;
И в .с:
void filesLoad(Jeux* tJeux){
(...)
tJeux = malloc(sizeof(Jeux));
fscanf(flot,"%d%*[^\n]\n", &tJeux->id);
printf("id stocked: %d\n", tJeux->id);
fclose(flot);
}
int main(void){
Jeux* tJeux;
filesLoad(tJeux);
printf("id stocké: %d\n", tJeux->id);
}
Теперь проблема: по какой-то причине printf в функции работает отлично, но тот, что за пределами filesLoad, вызывает сбой моей программы, помогите?
Я думаю, что это должно быть что-то. нравиться:
void filesLoad(Jeux* tJeux)
{
(...)
fscanf(flot,"%d%*[^\n]\n", &tJeux->id);
printf("id stocked: %d\n", tJeux->id);
fclose(flot);
}
int main(void)
{
Jeux* tJeux = (Jeux*) malloc(sizeof(Jeux));
filesLoad(tJeux);
printf("id stocké: %d\n", tJeux->id);
}
Делать это нужно в основном, потому что tJeux
размещался в filesLoad
стеке функции, и после возврата из функции он будет удален.
Обновлено: извините, у меня нет большого опыта в предоставлении ответов при переполнении стека. Спасибо за критику.
Я выделил структуру в основном, а не в функции.
Я отредактировал свой ответ. Спасибо за вашу критику @underscore_d. Я не подумал сначала дать объяснение :O
Вы переназначаете tJeux
внутри функции только что выделенному фрагменту памяти, но это изменение никогда не распространяется обратно на main
.
Вместо этого, возможно, заставить filesLoad
записать в предварительно выделенный объект:
typedef struct { int id; } Jeux;
void filesLoad(Jeux *tJeux) {
// ...
fscanf(flot, "%d%*[^\n]\n", &tJeux->id);
}
int main(void) {
Jeux *tJeux = malloc(sizeof(Jeux));
filesLoad(tJeux); // Load a file into `tJeux`
printf("id stocké: %d\n", tJeux->id);
}
Кроме того, у вас может быть функция, которая выделяет и загружает Jeux
(но помните, что в конечном итоге ответственность за освобождение Jeux будет лежать на вызывающем объекте):
typedef struct { int id; } Jeux;
void filesLoad(Jeux *tJeux) {
// ...
fscanf(flot, "%d%*[^\n]\n", &tJeux->id);
}
Jeux* allocateAndFilesLoad() {
Jeux* tJeux = malloc(sizeof(Jeux));
filesLoad(tJeux);
return tJeux;
}
int main(void) {
Jeux *tJeux = allocateAndFilesLoad();
printf("id stocké: %d\n", tJeux->id);
}
Если вы хотите что-то изменить в функции, которая существует вне этой функции, вы эмулируете передачу по ссылке, передавая указатель на нее и разыменовывая этот указатель:
void change(int *pVal) { *pVal = 42; }
int val = 7;
change(&val);
// Now it's 42.
Это ничем не отличается от изменения указателя, но вам нужно передать указатель на указатель, например:
void filesLoad(Jeux **ptJeux){
*ptJeux = malloc(sizeof(Jeux));
fscanf(flot,"%d%*[^\n]\n", &(*ptJeux)->id);
printf("id stocked: %d\n", (*ptJeux)->id);
fclose(flot);
}
int main(void){
Jeux* tJeux;
filesLoad(&tJeux);
:
}
Если вам разрешено изменять прототип filesLoad
, вы можете использовать любой из приведенных ниже способов.
Если вам не разрешено меняться, то путь, предложенный @AKX, — это путь.
Способ 1. вернуть адрес выделенной памяти (вызов по значению)
Jeux* filesLoad(void) {
(...)
Jeux* tJeux = malloc(sizeof(Jeux));
fscanf(flot,"%d%*[^\n]\n", &tJeux->id);
printf("id stocked: %d\n", tJeux->id);
fclose(flot);
return tJeux;
}
int main(void){
Jeux* tJeux;
tJeux = filesLoad(tJeux);
printf("id stocké: %d\n", tJeux->id);
}
Способ 2: передать адрес (звонить по ссылке)
void filesLoad(Jeux** tJeux){
(...)
*tJeux = malloc(sizeof(Jeux));
fscanf(flot,"%d%*[^\n]\n", &((*tJeux)->id));
printf("id stocked: %d\n", *tJeux->id);
fclose(flot);
}
int main(void){
Jeux* tJeux;
filesLoad(&tJeux);
printf("id stocké: %d\n", tJeux->id);
}
Зачем Jeux* filesLoad(Jeux* tJeux)
принимать указатель tJeux
, если он просто его выбросит?
@AKX, не могли бы вы немного уточнить, я не смог получить ваш комментарий.
Первое, что делает предложенная вами функция filesLoad
, — это переназначает новое значение tJeux
, так зачем вообще принимать аргумент?
А, понял!! filesLoad
может быть Jeux* filesLoad(void)
для метода 1, верно? Я торопился к чему-то другому, а потом особо не раздумывал.
Что вы изменили и почему это помогает? Ответ без объяснения гораздо менее полезен, чем ответ с.