所以我有这个结构,我将其用作解析器的树。
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”。 但我的程序在这一行崩溃了,此时我已经尝试了许多其他策略。
最佳答案
问题是您没有管理字符串的内存,因此您不能只使用 strcpy
。例如,当您有:
ret->value = (char*)malloc(sizeof(char));
ret->value = "18killstreak";
这为 0 长度的字符串(只是一个 NUL)分配空间,然后将其丢弃(内存泄漏),用指向静态常量字符串的指针覆盖分配的指针“18Killstreak”
。当您稍后尝试覆盖静态常量字符串(使用 strcpy
)时,您会崩溃。
因此,要正确执行此操作,您需要为字符串分配和管理内存。最简单的方法是让每个 struct Expr 拥有字符串的内存,并适本地使用 strdup/free 来分配/复制/释放该内存。所以你的初始化函数变成:
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");
稍后当您想要替换结构的值
时,您可以:
free(temp2->value);
temp2->value = strdup(ret->a->value);
当您想要释放Expr
时,您还需要(首先)释放值
:
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;
}
关于c - 复制结构中包含的字符串指针时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47743720/