gpt4 book ai didi

更改结构字符串

转载 作者:行者123 更新时间:2023-11-30 15:44:49 27 4
gpt4 key购买 nike

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

这是两个结构:

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

这是insertSymbol(SymbolTable* st, SymbolEntry entry)的相关代码。 pos插入时始终是数组中的最后一个元素(否则该条目不唯一并且 pos 只是返回)。

st->entries[pos].name = (char *)calloc(strlen(entry.name)+1, sizeof(char));
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].name, entry.name);
strcpy(st->entries[pos].type, entry.type);
strcpy(st->entries[pos].value, entry.value);

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

table.entries[prevSym].value = (char *)calloc(yyleng+1, sizeof(char));
strcpy(table.entries[prevSym].value, yytext);

为什么这会使数组中此位置的 SymbolEntry 无效,以及如何安全地更改 value 的内容?

编辑: 它不仅仅发生在常数上。前两个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怎么知道free()realloc()是第二种而不是第一种。进一步关注:同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);

关于更改结构字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19320732/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com