首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >结构分配:段故障11

结构分配:段故障11
EN

Stack Overflow用户
提问于 2015-03-17 04:14:10
回答 1查看 104关注 0票数 0
代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

union value {
    long long i;
    unsigned long long u;
    double d;
    long double ld;
    void *p;
    void (*g) ();
};

struct foo {
    struct {
        union value max;
        union value min;
    }limits;
};

struct bucket_info {
    void *p;                    // free position
    void *limit;                // end position
    struct bucket_info *next;   // next bucket
};

#define NODES 8192

void * my_malloc(size_t size)
{
    void *p = malloc(size);
    if (!p)
        exit(1);
    memset(p, 0, size);
    return p;
}

void * alloc_bucket(size_t size)
{
    struct bucket_info *pb;

    pb = my_malloc(sizeof(struct bucket_info) + size);
    pb->p = pb + 1;
    pb->limit = (char *)pb->p + size;
    return pb;
}

void * alloc_for_size(struct bucket_info *s, size_t size)
{
    void *ret;

    while (s->next)
        s = s->next;

    if ((char *)s->p + size > (char *)s->limit) {
        struct bucket_info *pb = alloc_bucket(size * NODES);
        s->next = pb;
        s = pb;
    }

    ret = s->p;
    s->p = (char *)s->p + size;
    return ret;
}

static void * alloc_node(struct bucket_info **s, size_t size)
{
    if (!*s)
        *s = alloc_bucket(size * NODES);
    return alloc_for_size(*s, size);
}

static struct bucket_info *foo_info;
void * alloc_foo_node()
{
    void *ret = alloc_node(&foo_info, sizeof(struct foo));
    return ret;
}

struct foo * new_foo()
{
    return alloc_foo_node();
}

void test(int t, struct foo *foo1)
{
    struct foo *foo2 = new_foo();
    // Crash at this line
    *foo2 = *foo1;
    // comment this switch statement, it works. why?
    switch (t) {
        case 1:
            break;

        default:
            break;
    }
}

int main(int argc, const char * argv[]) {

    struct foo *foo1 = new_foo();
    test(10, foo1);

    return 0;
}

以上是完整的代码。我用clang编译了它,得到了一行“段故障11”:

代码语言:javascript
复制
*foo2 = *foo1;

然后,将这一行更改为:

代码语言:javascript
复制
memcpy(foo2, foo1, sizeof(struct Foo));

它起作用了。

然后我和gcc一起编了这两件案子,没问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-17 05:39:58

alloc_foo_node返回的值可能不能正确地对齐struct foo

在我的系统中,打印_Alignof(struct foo)会给出16,但是指针foo1foo2并不是16的倍数。

因此,它会导致未定义的行为将alloc_foo_node的未对齐结果转换为struct foo *类型。

要解决这个问题,您必须在分配代码中花费更多时间,以确保它只分配位于struct foo正确边界上的空间。您可以使用max_align_t来帮助这一点(定义它是为了使_Alignof(max_align_t)成为所需的最大可能对齐)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29091184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档