0

When I call the "InitAnimation" function, I pass the the address of my object RG. When I assign the "animationName" field of that object, I can successfully print that field. But when I return to main and call the function "ReportAnimation", I am unable to print that value and my program crashes ? How come when I assigned that objects field it is not changed globally but only in the local function ?

I have tried allocating memory for the animationName field as well but that does not work.

struct Frame {
    char* frameName;
    struct Frame* pNext;
};

typedef struct {
    char* animationName;
    struct Frame* frames;
}Animation;


int main(void) {

    char response;

    BOOL RUNNING = TRUE;

    Animation RG;

    InitAnimation(&RG);

    while (RUNNING) {
        printf("MENU\n Enter 1 to ReportAnimation\n");
        scanf("%c", &response);

        switch (response) {
        case '1':InsertFrame(&RG); 
        break;
    }
    }

    return 0;
}

void InitAnimation(Animation* pointer) {

    pointer = (Animation*)malloc(sizeof(Animation));

    char* input;
    input = (char*)malloc(sizeof(input));

    printf("Please enter the Animation name:");
    fgets(input, 32, stdin);

    //pointer->animationName = (char*)malloc(sizeof(char)*10);

    //Setting animation name
    pointer->animationName = input;


    //This print function works
    printf("\nThe name is %s", pointer->animationName);

}

void ReportAnimation(Animation* pointer) {

    //This print function does not work
    printf("Animation name is %s\n", pointer->animationName);

}

I want the initAnimation function to change the field of the Animation struct and I want the reportAnimation function to print out the field, proving its changed

2
  • 1
    "Do I cast the result of malloc?" No. Commented Sep 12, 2019 at 23:50
  • In InitAnimation, pointer is already pointing to an Animation variable from the caller, so the pointer = malloc(sizeof(Animation)); is superfluous, and wrong, and a memory leak. Also input = malloc(sizeof(input)); will allocate a pointer sized chunk of memory (probably 4 or 8 bytes long), which is probably not the size you want since you pass the size 32 to fgets. Commented Sep 12, 2019 at 23:58

1 Answer 1

1

Changing the value of a function's variable (including those declared as parameters) has no effect on the caller.

void bad1(int i) {
   i = 1;  // No effect on the caller.
}

void bad2(void* p) {
   p = NULL;  // No effect on the caller.
}

If you want to change a variable in the caller, you will need to pass a pointer to it.

void good1(int* i_ptr) {
   *i_ptr = 1;
}

void good2(void** p_ptr) {
   *p_ptr = NULL;
}

So either pass a pointer to a pointer, or pass a pointer to an-already allocated structure. You could use

Animation ani;
Animation_init(&ani, name);
...
Frame* frame = Frame_new(name);
Animation_append_frame(&ani, frame);
...
Animation_destroy(&ani);

or

Animation* ani = Animation_new(name);
...
Frame* frame = Frame_new(name);
Animation_append_frame(ani, frame);
...
Animation_delete(ani);

assuming you had

typedef struct Frame {
    char* name;
    struct Frame* next;
} Frame;

typedef struct {
    char* name;
    Frame* first_frame;
    Frame* last_frame;
} Animation;

void Animation_init(Animation* self, const char* name) {
    self->name = strdup(name);
    self->first_frame = NULL;
    self->last_frame = NULL;
}

void Animation_destroy(Animation* self) {
    Frame* head = self->first_frame;
    while (head != NULL) {
       Frame* next = head->next;
       Frame_delete(head);
       head = next;
    }

    free(self->name);
}

Animation* Animation_new(const char* name) {
    Animation* self = malloc(sizeof(Animation));
    Animation_init(self, name);
    return self;
}

void Animation_delete(Animation* self) {
    Animation_destroy(self);
    free(self);
}

void Animation_append_frame(Animation* self, Frame* frame) {
   if (self->last_frame == NULL) {
      self->first_frame = frame;
   } else {
      self->last_frame->next = frame;
   }

   while (frame->next != NULL)
      frame = frame->next;

   self->last_frame = frame;
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.