Borrowed doesn’t mean immortal.
“Zero-copy.” Also zero guarantees that the thing you borrowed still exists. Nice optimization.
The mess
Your AI replaces copies with borrowed access. “Optimized.” Yes, accessing dead storage is wonderfully cheap if correctness isn't a requirement.
A reference aliases an object; a pointer stores an address. A view borrows data. None automatically keeps its target alive. Having someone's address doesn't stop them moving.
std::vector<int> scores{10};
int* first = &scores[0];
scores.reserve(scores.capacity() + 1); // New storage, if successful.
std::cout << *first; // Visiting the demolished house.
Assume the requested capacity is representable. Successful reallocation invalidates pointers and references to the old elements. The vector survives. Your pointer's usefulness doesn't.
The fix
Obtain the element again after reallocation, checking that the index is valid. Or prevent invalidation while borrowing.
A std::string_view also needs its backing characters to remain alive and valid. const restricts modification through an access path; it isn't life insurance.
Check both lifetime and invalidation. “The container still exists” is half a defense.
Ask your AI
Who owns this borrowed data? What destroys or invalidates it? Fix every use that crosses either event, citing the container's guarantees.
Receipts: Vector reallocation · String views.
Did that actually stick?
Three questions. “The AI said so” is not an answer.