所以我有这个结构,它用作解析器的树。
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"分别。 但是我的程序在这条线上崩溃了,此时我还尝试了很多其他的策略。
答案 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;
}