std::vector.data() 是否在指针向量上以 null 结尾?
Is std::vector.data() null-terminated on a vector of pointers?
我在我的 C++ 应用程序中使用 C 库。
其中一个函数需要 null-terminated array of pointers
.
因为我使用的是 C++,所以我将数组的元素存储在 std::vector
。
我想知道简单地调用我的向量 data()
并将结果传递给库函数是否安全。
例子:
std::vector<struct A *> vec;
//library_function(struct A **array);
library_function(vec.data());
当然,如果我更改向量中的元素,那么 data()
返回的指针将失效,但这不是问题(我可以在更新向量时再次调用该函数)。
我只是担心这可能是未定义的行为,因为我在任何地方都看不到 提到 data()
是由空指针而不是随机垃圾终止的.
标准确实说:
const T* data() const noexcept;
Returns pointer to the underlying array serving as element storage.
The pointer is such that range [data(); data() + size()) is always a valid range
所以有一个终止元素,但它没有说明该元素是否已初始化,如果已初始化,其值是多少。
它是否在我遗漏的其他地方指定?
还是我必须自己分配一个原始数组并用 null 终止它?
如果向量的最后一个元素为空,则指针向量以空结尾。最后一个元素之后没有额外的空元素(就像 std::string
的最后一个元素之后会有一个空终止符)。向量的最后一个元素不会自动为 null。如果您需要最后一个元素为空,则必须插入空元素。
示例:
std::vector<A> vec_of_struct(size);
std::vector<A*> vec_of_ptrs;
vec_of_ptrs.reserve(size + 1);
std::ranges::copy(
std::views::transform(
vec_of_struct,
[](A& a) { return &a; }
),
std::back_inserter(vec_of_ptrs)
);
vec_of_ptrs.push_back(nullptr); // null terminator pointer
library_function(vec_of_ptrs.data()); // C function
我在我的 C++ 应用程序中使用 C 库。
其中一个函数需要 null-terminated array of pointers
.
因为我使用的是 C++,所以我将数组的元素存储在 std::vector
。
我想知道简单地调用我的向量 data()
并将结果传递给库函数是否安全。
例子:
std::vector<struct A *> vec;
//library_function(struct A **array);
library_function(vec.data());
当然,如果我更改向量中的元素,那么 data()
返回的指针将失效,但这不是问题(我可以在更新向量时再次调用该函数)。
我只是担心这可能是未定义的行为,因为我在任何地方都看不到 提到 data()
是由空指针而不是随机垃圾终止的.
标准确实说:
const T* data() const noexcept;
Returns pointer to the underlying array serving as element storage.
The pointer is such that range [data(); data() + size()) is always a valid range
所以有一个终止元素,但它没有说明该元素是否已初始化,如果已初始化,其值是多少。
它是否在我遗漏的其他地方指定?
还是我必须自己分配一个原始数组并用 null 终止它?
如果向量的最后一个元素为空,则指针向量以空结尾。最后一个元素之后没有额外的空元素(就像 std::string
的最后一个元素之后会有一个空终止符)。向量的最后一个元素不会自动为 null。如果您需要最后一个元素为空,则必须插入空元素。
示例:
std::vector<A> vec_of_struct(size);
std::vector<A*> vec_of_ptrs;
vec_of_ptrs.reserve(size + 1);
std::ranges::copy(
std::views::transform(
vec_of_struct,
[](A& a) { return &a; }
),
std::back_inserter(vec_of_ptrs)
);
vec_of_ptrs.push_back(nullptr); // null terminator pointer
library_function(vec_of_ptrs.data()); // C function