Printf не работает вне функции с указателем на структуру

В моем проекте все сильно упрощено, поэтому, например, здесь в структуре только один 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, вызывает сбой моей программы, помогите?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
122
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Я думаю, что это должно быть что-то. нравиться:

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 23.12.2020 15:17

Я выделил структуру в основном, а не в функции.

jpkmiller 23.12.2020 15:19

Я отредактировал свой ответ. Спасибо за вашу критику @underscore_d. Я не подумал сначала дать объяснение :O

jpkmiller 23.12.2020 15:27
Ответ принят как подходящий

Вы переназначаете 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 23.12.2020 15:21

@AKX, не могли бы вы немного уточнить, я не смог получить ваш комментарий.

IrAM 23.12.2020 15:27

Первое, что делает предложенная вами функция filesLoad, — это переназначает новое значение tJeux, так зачем вообще принимать аргумент?

AKX 23.12.2020 17:07

А, понял!! filesLoad может быть Jeux* filesLoad(void) для метода 1, верно? Я торопился к чему-то другому, а потом особо не раздумывал.

IrAM 23.12.2020 17:12

Другие вопросы по теме