关于std::vector<std::array<double, dim>>与std::vector<double>底层存储等价性及指针使用安全性的疑问
Yes, you can safely use the pointer from vad.data()->data() as if it were returned by an equivalent std::vector<double>::data(), and this is guaranteed by the C++ standard with no aliasing issues or undefined behavior (UB) — provided you don’t access memory beyond the valid range of doubles.
Here’s a breakdown of why this works:
Contiguous Storage Guarantees
The key points from the C++ standard that ensure your approach is valid are:
std::vectorstores elements contiguously: For any non-boolstd::vector<T>, the standard mandates that&v[n] == &v[0] + nfor all valid indicesn. This means thestd::arrayobjects in yourvadvector are laid out back-to-back in memory with no gaps between them.std::arrayhas no internal padding: The size ofstd::array<double, dim>is exactlydim * sizeof(double)(per [array]/4 in the C++ standard). There are no hidden bytes or padding between thedoubleelements inside astd::array, and thestd::arrayitself has no extra overhead.- Combined effect: The entire
std::vector<std::array<double, dim>>occupies a single contiguous block of memory containing exactly(size/dim) * dim = sizedoublevalues. The pointervad.data()->data()points to the firstdoublein this block, so you can treat it identically to a pointer fromstd::vector<double>::data().
No Aliasing Violations
The strict aliasing rule (which restricts how you can access objects through different pointer types) does not apply here. You’re accessing double objects using a double* pointer, which is explicitly allowed by the rule. There’s no type mismatch or invalid aliasing happening in your code.
Important Caveats
While your approach is safe, keep these points in mind:
- Don’t exceed valid memory: Ensure you never read or write more than the total number of
doubles in the vector (i.e.,sizein your example). Accessing beyond this range is undefined behavior. - This only applies to
std::array: This logic works becausestd::arrayis a lightweight, padding-free wrapper for fixed-size arrays. If you used a vector of a custom struct (with potential padding between elements or non-contiguous internal data), this guarantee would not hold.
In your code example, when you use scan_vad to iterate through the doubles, you’re correctly accessing the contiguous block of memory. The output confirms that the values are laid out exactly as they would be in a std::vector<double>.
内容来源于stack exchange

