过去几个月我一直在用C搅拌。为了学习该语言,该项目是一个算术解析器 - 公式,变量等。
我最近决定继续进行垃圾收集,因为我对这个方法有很多调用:
char* read_token(const Source* source, const Token* token) {
int szWord = token->t_L + 1; // +1 for NULL terminator
char* word = (char*)malloc(sizeof(char)*szWord);
memset(word, '\0', sizeof(char)*(szWord));
char* p_T = source->p_Src + token->t_S;
memcpy(word, p_T, token->t_L);
return word;
}
...这意味着要调用free(...)
。
Source
结构有两个缓冲区属性:
typedef struct source Source;
struct source {
// ...
char* p_Src; // malloc'd source buffer
int srcLen;
Token* p_tokens; // malloc'd Token buffer
// ...
};
Token
结构具有开始和长度属性:
typedef struct token Token;
struct token {
int t_S; // buffer start index
int t_L; // token length
};
此外,由于可能有很多source
s,Source*
缓冲区为malloc
' d。
当缓冲区为malloc
时,提供结构的大小(* numStructs
)。但是,如果给定的struct有一个可以在以后分配的缓冲区,例如Token*
,那会改变Source
的大小吗?代码是否有覆盖先前分配的内存的危险?
出于某种原因,我认为用于结构的所有内存(包括任何缓冲区)都是以线性方式分配的。如果struct中的Token*
缓冲区被分配给10个令牌,那么该空间不会在Source
结构中线性分配吗?
答案 0 :(得分:1)
struct
中的指针成员是存储内存块地址的变量,当你自己指出指针和指针是独立分配时。因此,这些缓冲区可能位于其“父”struct
存储位置的旁边,或者不存在(很可能不会)。
如果需要,可以通过在struct
函数的一次调用中分配所有内容来确保*alloc
成员及其指向缓冲区的连续存储。
可以这样做
sizeof(struct foo)
的值。答案 1 :(得分:0)
结构中的指针是固定大小,无论它指向什么,即使它未被初始化。这样,sizeof(struct token)
是固定长度。
当使用malloc
时,内存从堆中取出,我们不知道在哪里,也不应该关心。在原始结构附近的任何地方都不太可能分配内存,即使它是,那也是特定于实现的,你不能指望这种行为。
显然(?)你应该在它所在的结构被销毁之前调用指针上的free()
。
另请注意C99的Variable Length Arrays(VLA)。
答案 2 :(得分:0)
抱歉,我在“答案”部分而不是“评论”部分写这个,因为我的Stackoverflow声誉还不够高。 我要评论的是你为什么不使用这一行:
char word[ sizeof(char)*szWord ];
而不是
char* word = (char*)malloc(sizeof(char)*szWord); ?