这是一个双循环链接。关于我的问题,不发布dev_num、blk_num和status。

   typedef struct buf_node {
    unsigned            dev_num;
    unsigned            blk_num;
    unsigned            status:2;
    struct buf_node     *ptr_prev_free_q;
    struct buf_node     *ptr_next_free_q;
    } stc_buf_header;

这是一个缓冲节点,它包含一个标识buf_头和一个数据字段
 typedef struct {
    stc_buf_header      *buf_header;
    stc_mm              *data_area;
    } stc_buffer;

这是双循环链接,它保存等待使用的空闲缓冲区节点(如UNIX)
typedef struct free_lk_node {
    stc_buffer          *lk_header;
    unsigned            len;
} stc_free_lk;

现在我定义了一个函数来初始化双循环链接
int init(stc_buffer *lk_header, unsigned dev_num, unsigned blk_num){

printf("buf_header\t%p\n", lk_header->buf_header);
printf("lk_header\t%p\n", lk_header);

printf("dev_num\t%d\n", lk_header->buf_header->dev_num);
printf("blk_num\t%d\n", lk_header->buf_header->blk_num);

lk_header->buf_header->dev_num = dev_num;
lk_header->buf_header->blk_num = blk_num;
lk_header->buf_header->status = 0x0;
lk_header->buf_header->ptr_next_free_q = lk_header->buf_header;
lk_header->buf_header->ptr_prev_free_q = lk_header->buf_header;
lk_header->data_area->data = -1; // means that this node is header of the          link
}

printf()语句被用来调试我得到这个bug的时候。
好吧,现在,如果我在main()中这样写的话
int main(){
    stc_free_lk *link = (stc_free_lk*)malloc(sizeof(stc_free_lk));
    init(link->lk_header, (unsigned)0, (unsigned)0);

    return 0;
}

当它运行到printf()语句处时,将引发一个段Fualt错误
但是,如果我在main()中这样写的话
int main(){
    stc_free_lk link;
    init(link.lk_header, (unsigned)0, (unsigned)0);

    return 0;
}

一切都好。为什么??,这让我困惑…(-o-)#

最佳答案

首先,使用%p来打印地址,而不是%d
你的问题是malloc只是分配内存,而不是初始化它。而您malloc调用只初始化struct stc_free_lk对象的内存,它不为指针成员分配内存,您还需要为它们分配内存。
所以lk_header->buf_header指的是无处,你不能取消引用它,它是未定义的行为。
你看到的是一个典型的行为不明的案例。
就像我说的,在访问它们之前,必须初始化结构的成员。
您可以使用calloc而不是malloc,因为calloc设置分配的
内存到0,这有助于在结构中初始化指针。

stc_free_lk *link = calloc(1, sizeof *link);
if(link == NULL)
{
    fprintf(stderr, "Not enough memory\n");
    return 1;
}

link->header = calloc(1, sizeof *link->header);
if(link->header == NULL)
{
    fprintf(stderr, "Not enough memory\n");
    free(link);
    return 1;
}

init(link->lk_header, (unsigned)0, (unsigned)0);
...

然后在init中,还应该为lk_header->buf_header
lk_header->data_area等等。
我建议您编写一个函数,将所有内存分配给
指针,这样就不必在不同的位置分配内存。那个
使代码难以遵循和查找错误。我也会写一个destroy
所有分配内存的函数,同样都在一个地方。

关于c - 在我分配内存后将ptr传递给函数时出现段错误,但是如果我不分配内存,那很有趣吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49713376/

10-11 22:51
查看更多