分段错误,大小为4的无效写入

问题描述 投票:3回答:1

我具有以下结构:

typedef struct ann_t {
  uint32_t xs;
  uint32_t hs;
  uint32_t ys;
  float *x;
  float *h;
  float *y;
  float **wxh;
  float **why;
} ann_t;

通过以下方式初始化:

ann_t* ann_init(uint32_t xs, uint32_t hs, uint32_t ys) {
  ann_t *ann = malloc(sizeof(ann_t));
  ann->xs = xs;
  ann->hs = hs;
  ann->ys = ys;
  ann->x = calloc(xs, sizeof(float));
  ann->h = calloc(hs, sizeof(float));
  ann->y = calloc(ys, sizeof(float));


  ann->wxh = calloc(xs, sizeof(float*));
  ann->why = calloc(hs+1, sizeof(float*));


  int i, j;
  for(i = 0; i < xs; i++) {
    ann->wxh[i] = malloc(hs * sizeof(float));
  }

  for(i = 0; i < hs+1; i++) {
    ann->why[i] = malloc(ys * sizeof(float));
  }
  // printf("%p\n", ann->x);
  return ann;
}

在另一个程序中包含此代码:

  ...

  ann_t *ann = ann_init(25, 10, 4);
  // printf("%p\n", ann->x);
  ann->x[0] = 1.0;

  ...

结果是:

分段故障(核心已转储)

使用valgrind:

== 26436 ==使用大小为8的未初始化值

...

== 26436 ==

== 26436 ==大小为4的无效写入

...

== 26436 ==地址0x4c3a78000000000未堆栈,未分配或(最近)已释放]

我试图在一个较小的程序中复制它,但不能。

将结构更改为具有uint64_t而不是uint32_t解决了这个问题。

ann->x内打印指针ann_init,得到0x55601051f080,在0x1051f08000000000]外部。

为什么会这样?

编辑:

在其中一个文件中找到了罪魁祸首:

#pragma pack(1)

仍然不确定为什么会导致此问题。

如果我正在执行指针算术来访问结构字段,这是有道理的,但是我正在按名称访问结构字段,所以为什么它计算出错误的值?

为什么在初始化函数内部没问题,但是在外部访问失败?

我有以下结构:typedef struct ann_t {uint32_t xs; uint32_t hs; uint32_t ys;浮动* x;浮动* h;浮动* y;浮动** wxh;浮动**为什么; } ann_t;初始化于...

c memory struct valgrind
1个回答
2
投票

从对问题的评论中得出的答案...

© www.soinside.com 2019 - 2024. All rights reserved.