发出复制结构中包含的字符串指针

时间:2017-12-10 21:37:33

标签: c string parsing pointers struct

所以我有这个结构,它用作解析器的树。

struct Expr{
    struct Expr* a;
    char* value;
    struct Expr* b;
};

我用malloc这样初始化它。

Expr* initExp(){
    Expr* ret;
    ret = (Expr*)malloc(sizeof(Expr));
    ret->a = (Expr*)malloc(sizeof(Expr));
    ret->b = (Expr*)malloc(sizeof(Expr));
    ret->value = (char*)malloc(sizeof(char));
    ret->value = "18killstreak";
    ret->a->value = "18killstreak";
    ret->b->value = "18killstreak";
    return ret;
}

我已经在函数中写了更多内容,而不是我到目前为止调试过程中需要的内容以及打印树。 所以我想复制一个Expr * a->将值作为这样的Expr *值。

strcpy(temp2->value,ret->a->value);

虽然价值是" 18killstreak"和" x"分别。 但是我的程序在这条线上崩溃了,此时我还尝试了很多其他的策略。

1 个答案:

答案 0 :(得分:1)

问题在于,您没有为字符串管理记忆,因此您无法使用strcpy。例如,当你有:

ret->value = (char*)malloc(sizeof(char));
ret->value = "18killstreak";

这为0长度的字符串(只是一个NUL)分配空间,然后抛弃它(内存泄漏),用指向静态常量字符串"18Killstreak"的指针覆盖分配的指针。当您稍后尝试覆盖静态常量字符串(使用strcpy)时,您会崩溃。

所以要正确地做,你需要为字符串分配和管理内存。最简单的方法是让每个struct Expr拥有字符串的内存,并适当地使用strdup / free来分配/复制/释放该内存。所以你的init函数变成了:

Expr* ret;
ret = (Expr*)malloc(sizeof(Expr));
ret->a = (Expr*)malloc(sizeof(Expr));
ret->b = (Expr*)malloc(sizeof(Expr));
ret->value = strdup("18killstreak");
ret->a->value = strdup("18killstreak");
ret->b->value = strdup("18killstreak");

稍后当您想要替换结构的value时,您可以:

free(temp2->value);
temp2->value = strdup(ret->a->value);

当您想要释放Expr时,您还需要(首先)释放value

free(exp->value);
free(exp);

现在有一个问题是strdup不是标准C函数 - 它是POSIX函数。因此它可以在POSIX系统(例如Linux或OSX)上使用,但不能在非POSIX系统上使用。所以你可能需要自己定义它:

char *strdup(const char *str) {
    char *rv = malloc(strlen(str) + 1);
    if (rv) strcpy(rv, str);
    return rv;
}