结构中p *的潜在问题?

时间:2015-06-02 14:56:44

标签: c pointers struct buffer

过去几个月我一直在用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结构中线性分配吗?

3 个答案:

答案 0 :(得分:1)

struct中的指针成员是存储内存块地址的变量,当你自己指出指针和指针是独立分配时。因此,这些缓冲区可能位于其“父”struct存储位置的旁边,或者不存在(很可能不会)。

如果需要,可以通过在struct函数的一次调用中分配所有内容来确保*alloc成员及其指向缓冲区的连续存储。

可以这样做

  • 使用固定大小的缓冲区:不太方便,因为丢失了缓冲区大小的任何灵活性。另请注意,声明此值会相应地更新sizeof(struct foo)的值。
  • 使用C99的灵活数组成员或技巧在C99 C之前启用该功能:Allocate Pointer and pointee at once
  • 使用不推荐的hacks使用指针算法,注意编译器的对齐策略。

答案 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); ?