C 更改结构字符串

C 更改结构字符串,c,struct,segmentation-fault,lex,c-strings,C,Struct,Segmentation Fault,Lex,C Strings,我用莱克斯来实现一个扫描器。我想在解析时构建一个符号表。我有两个结构,SymbolEntry和SymbolTable(如下)。大多数时候,当我调用我的函数来插入一个符号(registerID,也在下面)时,我拥有该条目的所有信息。然而,当我有一个常数时,我也希望得到它的值,但是当我第一次创建条目时,这不是立即可用的。当我稍后在代码中尝试更改entries值时,我正在使该条目使用的整个内存块无效,并且名称和值是打印垃圾 以下是两个结构: typedef struct{ char* type

我用莱克斯来实现一个扫描器。我想在解析时构建一个符号表。我有两个结构,SymbolEntry和SymbolTable(如下)。大多数时候,当我调用我的函数来插入一个符号(registerID,也在下面)时,我拥有该条目的所有信息。然而,当我有一个常数时,我也希望得到它的值,但是当我第一次创建条目时,这不是立即可用的。当我稍后在代码中尝试更改entries值时,我正在使该条目使用的整个内存块无效,并且名称和值是打印垃圾

以下是两个结构:

typedef struct{
    char* type;
    char* name;
    char* value;
} SymbolEntry;
typedef struct{
    SymbolEntry *entries;
    size_t size;
    size_t capacity;
} SymbolTable;
这是registerID函数,在匹配
{id}
时调用
yytext
包含ID

int registerID(char* type){
    //create a new symbol entry with the specified type and name and a default value
    SymbolEntry e;
    e.type = type;
    e.name = (char *)calloc(yyleng+1, sizeof(char));
    strcpy(e.name, yytext);
    e.value = "";
    prevSym = insertSymbol(&table, e);
    return prevSym;
}
这是插入符号的相关代码(SymbolTable*st,SymbolEntry)<插入时,code>pos始终是数组中的最后一个元素(否则条目不是唯一的,只返回
pos

稍后,在lex框架匹配紧跟在常量名称后面的值之后,将执行此代码(直接在
{number}
的规则中)

为什么这会使数组中此位置的符号项无效,如何安全地更改
值的内容

编辑: 这不仅仅发生在常数上。前两个
SymbolEntry
s始终是垃圾。我想这可能意味着它们都是,但其他的只是没有被覆盖

此外,对
registerID
的后续调用似乎导致数据损坏。只有9个符号,只有前两个是垃圾,34个是前7个。在没有变量的情况下添加更多文本进行解析不会导致任何问题

已解决 事实证明,我只是不小心删除了一行代码,这就是导致错误的原因。我不小心删除了对
initSymbolTable
的调用。感谢chux问我如何初始化表。很抱歉。

2潜在问题

1-比较

// Fields set with non-malloc'ed memory
e.type = type;
e.value = "";
// Fields set with malloc'ed memory
st->entries[pos].type = (char *)calloc(strlen(entry.type)+1, sizeof(char));
st->entries[pos].value = (char *)calloc(strlen(entry.value)+1, sizeof(char));
strcpy(st->entries[pos].type, entry.type);
strcpy(st->entries[pos].value, entry.value);
这两种方法都将字段设置为有效内存,在第二种情况下,动态填充内存。问题在于后续使用。OP怎么知道第二种而不是第一种呢。进一步关注:对于
registerID(char*type)
,我们如何知道传递给
type
的值在以后通过字段
type
使用该指针时仍然有效。建议:

e.type = strdup(type); // or the usual strlen()+1, malloc() and copy
e.value = strdup("");
2-未显示
yyleng
的类型和设置。与strlen(e.name)
等相比,它可能不够大

[编辑]经过审核,我觉得
e.type=type是问题所在
e.type
需要自己的
type
副本

小调:考虑

// st->entries[pos].type = (char *)calloc(strlen(entry.type)+1, sizeof(char));
// strcpy(st->entries[pos].type, entry.type);
size_t Length = strlen(entry.type) + 1;
st->entries[pos].type = malloc(Length);
memcpy(st->entries[pos].type, entry.type, Length);

您如何分配st->entries[pos]?一种可能是您正在写入分配的内存。我开始将其大小设置为16,但如果曾经
size==capacity
,则我会重新分配两倍的大小。每次插入操作后都会执行此检查。此外,我尝试将SymbolEntry数组分配到1024,但仍然无效。我假设这只是一个输入错误,但只是以防万一:您在代码中调用insertSymbol(),但稍后引用insertSymbolTable()。啊,是的,这是一个输入错误。谢谢。我已将所有作业更改为
strdup()
calls
yyleng
由lex定义,是
yytext
的长度。每个记录中的每个字段只创建一次,但
type==CONSTANT
value
除外。然后它只在两个特定位置中的一个发生变化。此时(即使输入文件中没有常量),前3/32个SYMBOL条目已损坏。如果在每一步都使用
strdup()
,我看不出这是怎么回事。最糟糕的情况是,我应该处理内存溢出。Hmmm。对于调试目的,请考虑<代码> E.Nord= StrudUp(yyType)< /C>和 Tab.条目[PRYSPYM] . value = StrudUp(YyTr原文)——也许您已经做好了准备。如果这不能解决问题,则问题必须在未发布的代码中。@Jaws212如何分配
st
的内存?有一个全局变量
SymbolTable表
。它的引用在registerID中的
inputSymbol(&table,e)
中传递。我不确定您要我如何处理
strdup(yytext)
语句,但我已将所有
st->entries[pos].**=strdup(***)
更改为使用文字字符串,问题仍然存在。您在
表中输入了什么值。entries
st->entries
?(注意:不是您在
st->entries[pos]…
中输入的值)
e.type = strdup(type); // or the usual strlen()+1, malloc() and copy
e.value = strdup("");
// st->entries[pos].type = (char *)calloc(strlen(entry.type)+1, sizeof(char));
// strcpy(st->entries[pos].type, entry.type);
size_t Length = strlen(entry.type) + 1;
st->entries[pos].type = malloc(Length);
memcpy(st->entries[pos].type, entry.type, Length);