You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态指针数组存储结构体指针时出现段错误的问题排查

动态数组存储struct指针时触发段错误的问题

我正在开发一个功能:实现存储某类型struct指针的动态数组,但遇到了无法理解的异常行为。

通过测试的静态数组存储指针代码

TEST test_f_chunk_array(void) {
  f_chunk* first;
  f_chunk* second;

  test_f_chunk_array_setup(&first, &second);

  // just validating that the setup is working as expected.
  ASSERT_EQ_FMT(1ul, (*first->first)->bytes->offset, "%zu");
  ASSERT_EQ_FMT(5ul, (*second->first)->next->bytes->offset, "%zu");
  ASSERT_EQ_FMT(6ul, (*second->first)->bytes->offset, "%zu");

  f_chunk* arr[2] = {NULL};
  arr[0] = first;
  arr[1] = second;

  // original pointers were not mutated, not surprising.
  ASSERT_EQ_FMT(1ul, (*first->first)->bytes->offset, "%zu");
  ASSERT_EQ_FMT(5ul, (*second->first)->next->bytes->offset, "%zu");
  ASSERT_EQ_FMT(6ul, (*second->first)->bytes->offset, "%zu");

  f_chunk* first_chunk = arr[0];
  f_chunk* second_chunk = arr[1];

  // awesome, retrieval works as expected.
  ASSERT_EQ_FMT(1ul, (*first_chunk->first)->bytes->offset, "%zu");
  ASSERT_EQ_FMT(5ul, (*second_chunk->first)->next->bytes->offset, "%zu");
  ASSERT_EQ_FMT(6ul, (*second_chunk->first)->bytes->offset, "%zu");

  PASS();
}

触发段错误的动态数组代码

这段代码在使用malloc分配空间并存储指针后,访问原指针指向的struct成员时出现段错误:

TEST test_f_chunk_dynamic_array(void) {
  f_chunk* first;
  f_chunk* second;

  test_f_chunk_array_setup(&first, &second);

  // just validating that the setup is working as expected.
  ASSERT_EQ_FMT(1ul, (*first->first)->bytes->offset, "%zu");
  ASSERT_EQ_FMT(5ul, (*second->first)->next->bytes->offset, "%zu");
  ASSERT_EQ_FMT(6ul, (*second->first)->bytes->offset, "%zu");

  // using dynamic array.
  size_t size = 2;
  f_chunk** arr = malloc(size * sizeof(f_chunk*));

  arr[0] = first;
  arr[1] = second;

  /*
    sanity check, I wouldn't expect for the underlying struct to be mutated
    as the array would only assign a copy of the pointer value?  
  */
  ASSERT_EQ_FMT(1ul, (*first->first)->bytes->offset, "%zu");
  // ^^^^ segfaults.

  ASSERT_EQ_FMT(5ul, (*second->first)->next->bytes->offset, "%zu");
  ASSERT_EQ_FMT(6ul, (*second->first)->bytes->offset, "%zu");

  f_chunk* first_chunk = arr[0];
  f_chunk* second_chunk = arr[1];

  // this doesn't work either.
  ASSERT_EQ_FMT(1ul, (*first_chunk->first)->bytes->offset, "%zu");
  ASSERT_EQ_FMT(5ul, (*second_chunk->first)->next->bytes->offset, "%zu");
  ASSERT_EQ_FMT(6ul, (*second_chunk->first)->bytes->offset, "%zu");

  PASS();
}

我原本认为分配空间并存储指针地址不会修改指针指向的struct,但实际出现了段错误。以下是setup函数代码:

void test_f_chunk_array_setup(f_chunk** first, f_chunk** second) {
  f_bytes* first_bytes;
  f_bytes* second_bytes;
  f_bytes* third_bytes;
  f_bytes_new(&first_bytes, true, 1ul);
  f_bytes_new(&second_bytes, true, 5ul);
  f_bytes_new(&third_bytes, false, 6ul);


  f_bytes_node* first_node;
  f_bytes_node* second_node;
  f_bytes_node* third_node;
  f_bytes_node_new(&first_node, first_bytes);
  f_bytes_node_new(&second_node, second_bytes);
  f_bytes_node_new(&third_node, third_bytes);

  first_node->next = NULL;
  second_node->next = NULL;
  third_node->next = second_node;

  f_chunk* first_chunk;
  f_chunk* second_chunk;

  f_chunk_new(&first_chunk, 1, &first_node, &first_node);
  f_chunk_new(&second_chunk, 2, &third_node, &second_node);

  *first = first_chunk;
  *second = second_chunk;
}

内容的提问来源于stack exchange,提问作者Sean Gregory

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:49:55