C array of structure (exception thrown)

1

I have created an array of structure Human which consists of char *name.

I use function like this:

Human *createHuman(char *name){
    Human *h = malloc(sizeof(Human));
    h->name = strdup(name);
    return h;
}

I have tested this function, it works perfectly, but my problem starts when i use it like this:

void gen_Humans(Human array[MAX], int n){
    //n == max;
    for (int i = 0; i<n; i++){
        char *name = gen_name_function_used_before_WORKING();
        array[i] = *createHuman(*name);
    }
    …
}

As I said, if I generate one human it works just fine. I debugged my code and when I got to the point of strdup(name) it threw me this:

my error: Exception thrown at 0x53DCF6E0 (ucrtbased.dll) in project.exe:
0xC0000005: Access violation reading location 0x00000070.

I am using VS 2017 Enterprise.

c
arrays
string
struct
strdup
asked on Stack Overflow Apr 15, 2019 by MirEso • edited Apr 15, 2019 by Jonathan Leffler

2 Answers

1

When calling your function createHuman you are passing the value of your name:

array[i] = *createHuman(*name);

When building this application, Iam getting the following compiler warning (GCC):

warning: passing argument 1 of 'createHuman' makes pointer from integer without a cast

since your function createHuman expects the adress of the name, you should also pass the address. For example:

array[i] = *createHuman(name);
answered on Stack Overflow Apr 15, 2019 by Moritz Schmidt
1

Adding to @MortizSchmidt's answer:

  • You are not checking the results of malloc(). You should do so, even if the chances of failure are small.
  • You are leaking memory - since you never free the malloc()ed memory nor do you keep the pointer anywhere. Remember C is not like Java - assignment is not an assignment of a reference.
  • Note that the MAX indicator in the function signature doesn't have any effect. The parameter is an int* any way you write it: int* array, int array[] or int array[MAX].

Actually, why even allocate the Human structure rather than just space for the string?

struct Human createHuman(char *name){
    if (name == NULL) {
        struct Human h = { NULL };
        return h;
    }
    struct Human h = { strdup(name) };
    if (h.name == NULL) { /* handle error here */ }
    return h;
}

void gen_Humans(Human array[MAX], int n){
    for (int i = 0; i < n; i++) {
        char *name = gen_name_function_used_before_WORKING();
        array[i] = createHuman(name);
    }
    …
}

This has the added benefit of initializing all fields in Human after name to 0.

answered on Stack Overflow Apr 15, 2019 by einpoklum • edited Apr 15, 2019 by einpoklum

User contributions licensed under CC BY-SA 3.0