C 通过构造函数为结构指针成员分配空间

C 通过构造函数为结构指针成员分配空间,c,oop,malloc,C,Oop,Malloc,我想使用类似C中对象的结构 假设我有以下几点: typedef struct { /* ... */ size_t *pages_len; } book; 我使用以下方法来构建它: int book_init(/* some args... */, book * b) { /* do some validation */ /* compute the number of pages n_pages */ b->pages_len = (size_t

我想使用类似C中对象的结构

假设我有以下几点:

typedef struct {
    /* ... */
    size_t *pages_len;
} book;
我使用以下方法来构建它:

int book_init(/* some args... */, book * b) {
    /* do some validation */
    /* compute the number of pages n_pages */
    b->pages_len = (size_t*) calloc(n_pages, sizeof(size_t));
    /* compute pages_len based on some args */
    return 0;
}
然后我构造一个这样的对象:

book *my_book = (book*)malloc(sizeof(my_book));
if (book_init(/* some args */, my_book) == 0) {
    /* do something */
}
然后我销毁我的对象,比如:
book\u销毁(book*b)
free(b->pages\u len)

这是正确的还是我遗漏了什么?我无法显示原始代码,但遇到问题:

  • 在init方法之后访问
    b->pages\u len
  • 销毁该对象。我的记忆力衰退了
  • 根据要求,一个最小的可复制示例:

    /* book.h */
    #ifndef BOOK_HEADER_
    #define BOOK_HEADER_
    #include <ctype.h>
    
    typedef struct
    {
      size_t pages_count;
      size_t *pages_len;
    } * book;
    
    int book_create (book b);
    #endif /* BOOK_HEADER_ */
    
    我从内存泄漏检测器得到的是
    free(我的书)
    给出了
    内存损坏(写得越界?
    错误。修复此错误的一件事是更改
    pages\u count
    pages\u len
    的顺序,但我不知道为什么


    我只是打了上面的例子,所以如果有任何打字错误或语法错误,请让我知道。谢谢。

    book我的书=malloc(sizeof(book))
    错了。请注意,
    book
    的类型是指向结构的指针,但您希望为结构本身分配足够的空间。因此,就代码而言,您需要编写
    malloc(sizeof(*my_book))

    然而,使用
    typedef
    为指针定义名称通常是不好的风格;这会导致混淆,并且您会发现结构类型没有名称是非常尴尬的。写这篇文章的更好方法是

    struct book
    {
      size_t pages_count;
      size_t *pages_len;
    };
    
    struct book *my_book = malloc(sizeof(*my_book));
    
    在这种情况下,
    malloc(sizeof(structbook))
    也可以工作,但是如果您更改
    my_book
    的类型,它将被破坏

    经常有人建议您不要将
    struct
    键入def,而是一直到处调用它
    structbook
    ,因为记住您使用的对象类型通常是很好的。但如果必须,您仍然可以执行
    typedef struct book之后。如前所述,我不推荐
    typedef struct book*book

    在C中不需要强制转换
    malloc
    的结果。您可能包括它,因为您得到了关于
    malloc
    返回类型的警告,但正确的修复方法是包括标准头
    。事实上,这正是人们通常建议您不要强制转换
    malloc
    的结果的原因,因为它可以消除指示真正bug的警告。有关此主题的更多信息,请参阅

    您还需要
    test.c
    中的

    另外,
    create\u book
    应该返回一个值(但这不是崩溃的原因,因为您从未使用过它)

    重新排列结构成员使bug看起来消失了,这并不奇怪。可能发生的事情是这样的。在典型的64位系统上,
    size\u t
    和指针各为8字节。所以您为结构分配了8个字节,而它的大小实际上是16。但实际上您只给
    页面
    成员写信。因此,如果
    pages\u len
    是结构的第一个成员,并且您从未写入
    pages\u count
    成员,那么您只在分配的8个字节内写入,不会出错。当然,代码仍然被破坏,一旦添加了使用
    pages\u count
    成员的任何代码,或者添加或重新排列了结构的任何成员,错误就会回来


    但是一般来说,在用C语言编程时,盲目地改变事情直到bug消失是一个非常糟糕的主意。你可能很容易做一些只会掩盖bug的事情,让它更难被发现。没有什么可以代替实际理解正在发生的事情。

    book my_book=malloc(sizeof(book))
    是错误的。请注意,
    book
    的类型是指向结构的指针,但您希望为结构本身分配足够的空间。因此,就代码而言,您需要编写
    malloc(sizeof(*my_book))

    然而,使用
    typedef
    为指针定义名称通常是不好的风格;这会导致混淆,并且您会发现结构类型没有名称是非常尴尬的。写这篇文章的更好方法是

    struct book
    {
      size_t pages_count;
      size_t *pages_len;
    };
    
    struct book *my_book = malloc(sizeof(*my_book));
    
    在这种情况下,
    malloc(sizeof(structbook))
    也可以工作,但是如果您更改
    my_book
    的类型,它将被破坏

    经常有人建议您不要将
    struct
    键入def,而是一直到处调用它
    structbook
    ,因为记住您使用的对象类型通常是很好的。但如果必须,您仍然可以执行
    typedef struct book之后。如前所述,我不推荐
    typedef struct book*book

    在C中不需要强制转换
    malloc
    的结果。您可能包括它,因为您得到了关于
    malloc
    返回类型的警告,但正确的修复方法是包括标准头
    。事实上,这正是人们通常建议您不要强制转换
    malloc
    的结果的原因,因为它可以消除指示真正bug的警告。有关此主题的更多信息,请参阅

    您还需要
    test.c
    中的

    另外,
    create\u book
    应该返回一个值(但这不是崩溃的原因,因为您从未使用过它)

    重新排列结构成员使bug看起来消失了,这并不奇怪。可能发生的事情是这样的。在典型的64位系统上,
    size\u t
    和指针各为8字节。所以您为结构分配了8个字节,而它的大小实际上是16。但实际上您只给
    页面
    成员写信。因此,如果
    pages\u len
    是结构的第一个成员,并且您从不向
    struct book
    {
      size_t pages_count;
      size_t *pages_len;
    };
    
    struct book *my_book = malloc(sizeof(*my_book));