1

I'm still fairly new to programming in C, and still learning the language. I'm trying to do the following (its a scaled down version of my initial program code). But every time I try to initialize counter, the program crashes. I've tried setting up another function to handle the initialization process, setting up the counter to be incremented in the set_members function, and tried initializing the counter by passing it the address of total &total. But every time I try to run my program, it crashes after printing "Hello". I think I'm trying to initialize counter incorrectly because I don't fully understand pointers and structs in C. Can someone explain how or why my initialization process is incorrect, and causes my program to crash? And how I can do it correctly going forward? Thanks!

typedef struct CharStruct{
    char *names;
}CharStruct;

typedef struct Count{
    CharStruct *arr;
    int counter;
}Count;

typedef struct Members{
    Count *member;
}Members;

typedef struct Test{
    Members people;
}Test;

void set_members(struct Test *person);
void print_total(struct Test *person);

int main(void) {
    printf("Hello\n"); /* prints Hello */
    Test person;
    //person.people.member->counter = 0;
    set_members(&person);
    print_total(&person);
    system("pause");
    return EXIT_SUCCESS;
}

void set_members(struct Test *person)
{
    int total = 0;

    while(total < 10)
    {
        ++total;
    }
    person->people.member->counter = total;
}


void print_total(struct Test *person)
{
    printf("Total Members: %d\n", person->people.member->counter);
}
3
  • You didn't allocate memory for member. Member is a pointer and this pointer point to some memory that not for you at that time, you need allocate memory using malloc and after it work with it. person->people.member = malloc(sizeof(Count)); Commented Mar 11, 2018 at 16:11
  • I don't understand the meaning of the while loop in set_members, why are you doing this? Commented Mar 11, 2018 at 16:32
  • I also don't understand your structs, what kind of data are you modelling with these structs? Test contains a Members struct, Members contains a pointer to Count which contains a pointer of CharStruct? What problem are you trying to solve? Commented Mar 11, 2018 at 16:36

2 Answers 2

2

When you take a look at the:

typedef struct Members{
    Count *member;
}Members;

please notice that member is a pointer pointing to the Count type object. To be able to operate on that object the object has to exist. Memory for it has to be dynamically or statically allocated. Otherwise, the behavior of your program in undefined.

Check the memory allocation done in the sample program:

#include <stdio.h>
#include <stdlib.h>

typedef struct CharStruct{
    char *names;
}CharStruct;

typedef struct Count{
    CharStruct *arr;
    int counter;
}Count;

typedef struct Members{
    Count *member;
}Members;

typedef struct Test{
    Members people;
}Test;

void set_members(struct Test *person)
{
    int total = 0;
    while(total < 10){
        ++total;
    }
    person->people.member->counter = total;
}

void print_total(struct Test *person)
{
    printf("Total Members: %d\n", person->people.member->counter);
}

int main(void) {
    printf("Hello!\n"); /* prints Hello */ 
    Test person;     
#if 0 // allocate memory on stack
    Members m;
    Count   c;
    // use declared variables 
    person.people = m;  
    m.member = &c; 
#else    
    // or dynamic alocation
    person.people.member = malloc(sizeof(Count)); 
#endif

    set_members(&person);
    print_total(&person);

    person.people.member->counter = 77;
    print_total(&person);

    free(person.people.member);

    //system("pause");
    return EXIT_SUCCESS;
}

Output:

Hello!                                                                                                                                     
Total Members: 10                                                                                                                          
Total Members: 77

The memory for object of type Count where type Count

typedef struct Count{
    CharStruct *arr;
    int counter;
}Count;

was allocated by:

malloc(sizeof(Count));

It is worth to stress that you can use the int counterbut CharStruct *arr points to undefined memory location.

Again, to safely use member arr it has to point to a valid object of type CharStruct. You should allocate memory for the CharStruct. That is not all. Once you have object CharStruct it has char *names pointer for pointing to the string. If you want to use names it should point to the valid string!

Your chain of nested structures with pointers will require very careful memory handling for allocation and deallocation. Be aware of potential memory leaks or uninitialized pointers. Those are one of the most common problems encountered by many C programmers.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! That makes more sense. I didn't realize that I wasn't creating the object and allocating memory in advance to setting counter. Also, thanks for including a note to be mindful of memory leaks, and allocation/deallocation. That's important for me to remember.
0

person.people.member is a pointer which is not initialized. It has some garbage value which might be the address of some memory location that the program is not allowed to access.

As others have said, dereferencing an uninitialised pointer invokes undefined behavior.

You need to allocate memory for a struct Count and assign its address toperson.people.member before writing value to it.

You could do

person.people.member = malloc(sizeof(struct Count));

in main() right after declaring person or do

person->people.member = malloc(sizeof(struct Count));

in set_members() before the person->people.member->counter = total;.

And don't forget to deallocate the memory once you are done using it like

free(person->people.member);

The same thing goes for the other pointers person.people.member->arr and person.people.member->arr->names.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.