向vector添加对象指针后值异常变更的解决方案咨询
Alright, let's tackle your problem head-on. First, let's recap why you're seeing those garbage values: when you create a local B object inside your loop and push its address into vec, that local object lives on the stack. As soon as the loop iteration ends, the object is destroyed, leaving your vector full of dangling pointers—points to invalid memory. That's why vec[0]->one turns into garbage later.
Now, onto the solutions, since you can't modify the target function's signature (it needs a const raw pointer and vector size):
Solution 1: Use std::vector<std::unique_ptr<B>> (or shared_ptr)
Smart pointers manage heap-allocated objects automatically, so you won't have dangling pointers. To pass the raw const pointer the function needs, just use the get() method of the smart pointer.
Here's how to adjust your code:
// Replace raw pointer vector with unique_ptr vector std::vector<std::unique_ptr<B>> vec; for (const auto& a : input.buffer()) { // Allocate B on the heap instead of stack auto b = std::make_unique<B>(); // Assign values from the A object to B's members b->one = a.one; b->two = a.two; b->three = a.three; b->four = a.four; // Don't forget to set B's fifth member here too! // Transfer ownership of the unique_ptr to the vector vec.push_back(std::move(b)); } // Call the target function: get() returns a raw pointer, which implicitly converts to const B* function_which_needs_a_const_pointer_to_the_first_element_and_size_of_vector( vec.front().get(), vec.size() );
Why this works:
std::make_unique<B>allocates theBobject on the heap, so it doesn't get destroyed when the loop iteration ends.vec.front().get()returns a rawB*pointer, which can be implicitly converted toconst B*(since the function expects a const pointer). If you want to be explicit, you can cast it withstatic_cast<const B*>(vec.front().get()).unique_ptrensures the heap objects are automatically deleted when the vector goes out of scope, so no memory leaks.
If you prefer shared_ptr instead (e.g., if you need to share ownership elsewhere), the logic is almost identical—use std::make_shared<B> and std::vector<std::shared_ptr<B>>, then call get() the same way.
Solution 2: Use std::vector<B> (Store Objects Directly)
If your B struct is cheap to copy, this is an even simpler approach. Instead of storing pointers, store the actual B objects in the vector. The vector's internal storage is heap-allocated, so the objects will persist until the vector is destroyed.
// Store B objects directly, not pointers std::vector<B> vec; for (const auto& a : input.buffer()) { B b; // Assign values from A to B b.one = a.one; b.two = a.two; b.three = a.three; b.four = a.four; // Set B's fifth member // Copy the local B into the vector (vector stores it on the heap) vec.push_back(b); } // Pass the address of the first element (which is a valid, const pointer) function_which_needs_a_const_pointer_to_the_first_element_and_size_of_vector( &vec.front(), vec.size() );
Why this works:
- When you
push_back(b), the vector creates a copy ofbin its own heap-allocated buffer. The localbis destroyed, but the copy in the vector remains valid. &vec.front()gives you a raw pointer to the first element in the vector's buffer, which is exactly what the target function needs. Since the function expects a const pointer, the implicit conversion fromB*toconst B*works here too.
Key Takeaway
Your core issue was storing pointers to stack-allocated objects. Any solution that ensures the pointers point to persistent, heap-allocated memory (either via smart pointers managing heap objects, or a vector storing objects directly) will fix the dangling pointer problem and let you pass a valid const raw pointer to the target function.
内容的提问来源于stack exchange,提问作者Cihan Kurt

