Строковое поле struct как параметр функции в C

У меня есть структура

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);
}

Я хочу передать поле структуры.word в foo, и я ожидаю, что значение моего поля будет изменено после возврата из функции, но это не так:

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

Что я делаю неправильно?

2 ответа

Решение

Вы перезаписываете указатель destptr перешел к foo() по malloc'ing. Передать указатель на указатель из main() в foo():

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

и назвать как:

foo(&nodeptr->word, word);

В функции

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

параметры destptr а также srcptr являются локальными для функции foo, Они являются автоматическими переменными, т. Е. Имеют автоматическое распределение памяти. Это означает, что они размещаются в стеке при вызове функции и уничтожаются при возврате функции. призвание foo как

foo(nodeptr->word, word);

просто копирует значение nodeptr->word в destptr и из word в scrptr, Поэтому переменные nodeptr->word а также word не изменены. Выделение памяти и присвоение desptr в foo функция вызывает утечку памяти, так как эта память не свободна и дескриптор к ней теряется, когда foo возвращается.

Что вы должны сделать, это передать адрес nodeptr->word в foo и изменить подпись foo соответственно.

#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;
}
Другие вопросы по тегам