我正在处理一个用例,其中我希望有dynamic array个指针,这些指针指向某种类型的 struct .
我注意到一些奇怪的行为,我希望有人能帮忙澄清.
首先,我将使用static array个指针来分享passing test.
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();
}
现在,对于使用dynamic array的failing test人,我注意到了一些我不太理解的行为.
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 .
Edit个
分享设置,如果它有助于澄清.
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;
}
Second Edit个
最小可重复示例:https://godbolt.org/z/6c8z7coYq