Malloc 多个连接的结构,以便在类型检查器中分隔范围
Malloc multiple connected structs in order to seperate scopes in a type checker
我正在尝试创建一个名为 Block
的结构,该结构连接到另一个名为 Scope
的结构,该结构再次连接到另一个名为 Vars
的结构。这样做的原因是因为我正在尝试编写类型检查器并且需要确保分配给变量的值属于同一类型。
所以我能想到的最好的方法就是创建一个 Block
可以设置多个 Scopes
应该收集 {...}
块内的所有变量,当我们到达终点,弹出那个块并在前一个结束,足够简单..
嗯,这就是我得到的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
struct Vars{
char *var;
int type;
};
struct Scope{
struct Vars *vars;
int num_of_vars;
};
struct Block{
struct Scope *scope;
int num_of_scopes;
};
void
newScope(struct Block *block)
{
block->num_of_scopes++;
block->scope = realloc(block->scope, sizeof(struct Scope)*block->num_of_scopes);
block->scope[block->num_of_scopes--].num_of_vars = 0;
}
void addVarToScope(char *var, int type, struct Block *block)
{
block->scope[block->num_of_scopes--].num_of_vars++;
if(block->scope->num_of_vars == 0)
{
block->scope[block->num_of_scopes--].vars = malloc(sizeof(struct Scope));
}
else
{
block->scope[block->num_of_scopes--].vars = realloc(block->scope[block->num_of_scopes--].vars, sizeof(struct Scope)*block->scope->num_of_vars);
}
block->scope[block->num_of_scopes--].vars[block->scope->num_of_vars--].var = malloc(10);
strcpy(block->scope[block->num_of_scopes--].vars[block->scope->num_of_vars--].var, var);
block->scope[block->num_of_scopes--].vars[block->scope->num_of_vars--].type = type;
}
int
main()
{
struct Block *block;
block = malloc(sizeof(struct Block));
block->num_of_scopes = 0;
newScope(block);
addVarToScope("123456789", 0, block);
printf("%s\n", block->scope->vars[0].var);
return 0;
}
所有 block->num_of_scopes--
bs 的原因是因为它应该作为堆栈工作,我只对我所在的范围感兴趣,当我离开它时我打算释放它 space,因为我知道它没问题(或者如果类型检查失败则抛出错误)。正如您所看到的,这很快变得非常冗长和复杂,即使是在这个较小的测试文件中,也没有与我的解析器一起使用。上面的代码生成错误
main: malloc.c:2539: sysmalloc: Assertion `(old_top == initial_top
(av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE &&
prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) ==
0)' failed. [1] 102422 abort (core dumped) ./main
我以前从未见过这个错误,很难理解它。我已经通过 gdb 追踪到函数 addVarToScope
中的重新分配,但在我看来一切都应该没问题..
有谁知道问题出在哪里以及我应该如何解决?另外(也许更重要),有更好的方法吗?现在花了几天时间试图让它工作,但我想不出一个 better/more 干净的方法。
当你这样做时:
block->scope[block->num_of_scopes--].num_of_vars = 0;
block->num_of_scopes--
求得 block->num_of_scopes
的 当前 值,然后递减它。
因此,您不仅在第一次执行此操作时访问了数组末尾之后的一个元素,而且在后续使用中访问数组开始之前的内存时,您最终将该值减小为负值。这会触发 undefined behavior.
将 block->num_of_scopes--
的所有实例更改为 block->num_of_scopes-1
。
除此之外,block->scope
在您第一次将其传递给 newScope
时未初始化。第一次为 block
.
分配 space 时需要将其设置为 NULL
scope
的 vars
成员也有类似的问题。您永远不会输入 if(block->scope->num_of_vars == 0)
的 if
部分,因为您在该行之前递增了 num_of_vars
。 在 if
块之后执行此操作。
我正在尝试创建一个名为 Block
的结构,该结构连接到另一个名为 Scope
的结构,该结构再次连接到另一个名为 Vars
的结构。这样做的原因是因为我正在尝试编写类型检查器并且需要确保分配给变量的值属于同一类型。
所以我能想到的最好的方法就是创建一个 Block
可以设置多个 Scopes
应该收集 {...}
块内的所有变量,当我们到达终点,弹出那个块并在前一个结束,足够简单..
嗯,这就是我得到的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "main.h"
struct Vars{
char *var;
int type;
};
struct Scope{
struct Vars *vars;
int num_of_vars;
};
struct Block{
struct Scope *scope;
int num_of_scopes;
};
void
newScope(struct Block *block)
{
block->num_of_scopes++;
block->scope = realloc(block->scope, sizeof(struct Scope)*block->num_of_scopes);
block->scope[block->num_of_scopes--].num_of_vars = 0;
}
void addVarToScope(char *var, int type, struct Block *block)
{
block->scope[block->num_of_scopes--].num_of_vars++;
if(block->scope->num_of_vars == 0)
{
block->scope[block->num_of_scopes--].vars = malloc(sizeof(struct Scope));
}
else
{
block->scope[block->num_of_scopes--].vars = realloc(block->scope[block->num_of_scopes--].vars, sizeof(struct Scope)*block->scope->num_of_vars);
}
block->scope[block->num_of_scopes--].vars[block->scope->num_of_vars--].var = malloc(10);
strcpy(block->scope[block->num_of_scopes--].vars[block->scope->num_of_vars--].var, var);
block->scope[block->num_of_scopes--].vars[block->scope->num_of_vars--].type = type;
}
int
main()
{
struct Block *block;
block = malloc(sizeof(struct Block));
block->num_of_scopes = 0;
newScope(block);
addVarToScope("123456789", 0, block);
printf("%s\n", block->scope->vars[0].var);
return 0;
}
所有 block->num_of_scopes--
bs 的原因是因为它应该作为堆栈工作,我只对我所在的范围感兴趣,当我离开它时我打算释放它 space,因为我知道它没问题(或者如果类型检查失败则抛出错误)。正如您所看到的,这很快变得非常冗长和复杂,即使是在这个较小的测试文件中,也没有与我的解析器一起使用。上面的代码生成错误
main: malloc.c:2539: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. [1] 102422 abort (core dumped) ./main
我以前从未见过这个错误,很难理解它。我已经通过 gdb 追踪到函数 addVarToScope
中的重新分配,但在我看来一切都应该没问题..
有谁知道问题出在哪里以及我应该如何解决?另外(也许更重要),有更好的方法吗?现在花了几天时间试图让它工作,但我想不出一个 better/more 干净的方法。
当你这样做时:
block->scope[block->num_of_scopes--].num_of_vars = 0;
block->num_of_scopes--
求得 block->num_of_scopes
的 当前 值,然后递减它。
因此,您不仅在第一次执行此操作时访问了数组末尾之后的一个元素,而且在后续使用中访问数组开始之前的内存时,您最终将该值减小为负值。这会触发 undefined behavior.
将 block->num_of_scopes--
的所有实例更改为 block->num_of_scopes-1
。
除此之外,block->scope
在您第一次将其传递给 newScope
时未初始化。第一次为 block
.
scope
的 vars
成员也有类似的问题。您永远不会输入 if(block->scope->num_of_vars == 0)
的 if
部分,因为您在该行之前递增了 num_of_vars
。 在 if
块之后执行此操作。