Andrey Khataev
Andrey Khataev

Reputation: 1343

struct's string field as function's parameter in C

I have a struct

typedef struct HASH_NODE
{
    char*              word;
    struct HASH_NODE*  next;
} HASH_NODE;

and function

void foo(char* destptr, const char* srcptr)
{
    destptr = malloc(strlen(srcptr)+1);
    strcpy(destptr, srcptr);
}

I want to pass structs field .word to foo and I expect that value of my field would be changed after function return, but it doesn't:

int main (void)
{
    HASH_NODE* nodeptr = malloc(sizeof(HASH_NODE));
    nodeptr->next = NULL;
    nodeptr->word = NULL;
    char* word = "cat";
    foo(nodeptr->word, word);
}

What am I doing wrong?

Upvotes: 3

Views: 1151

Answers (2)

ajay
ajay

Reputation: 9680

In the function

void foo(char* destptr, const char* srcptr)
{
    destptr = malloc(strlen(srcptr)+1);
    strcpy(destptr, srcptr);
}

the parameters destptr and srcptr are local to the function foo. They are automatic variable, i.e., have automatic storage allocation. This mean they are allocated on the stack when the function is called and are destroyed when the function returns. Calling foo as

foo(nodeptr->word, word);

simply copies the value of nodeptr->word to destptr and of word to scrptr. Therefore, the variables nodeptr->word and word are not changed. Allocating memory and assigning to desptr in foo function causes memory leak since that memory is not free and handle to it is lost when foo returns.

What you should do is pass the address of nodeptr->word to foo and change the signature of foo accordingly.

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

typedef struct HASH_NODE
{
    char *word;
    struct HASH_NODE *next;
} HASH_NODE;

void foo(char **destptr, const char* srcptr)
{
    *destptr = malloc(strlen(srcptr)+1);
    strcpy(*destptr, srcptr);
}

int main (void)
{
    HASH_NODE *nodeptr = malloc(sizeof *nodeptr);
    if(nodeptr == NULL) {
        printf("not enough memory to allocate\n");
        return 1;
    }
    nodeptr->next = NULL;
    nodeptr->word = NULL;
    const char *word = "cat";
    foo(&nodeptr->word, word);

    // after done with nodeptr
    free(nodeptr->next);
    free(nodeptr);
    //
    return 0;
}

Upvotes: 0

P.P
P.P

Reputation: 121387

You are overwriting the pointer destptr passed to foo() by malloc'ing. Pass a pointer to pointer from main() to foo():

void foo(char** destptr, const char* srcptr)
{
    *destptr = malloc(strlen(srcptr)+1);
    strcpy(*destptr, srcptr);
}

and call as:

foo(&nodeptr->word, word);

Upvotes: 4

Related Questions