How to get std::vector pointer to the raw data?
&something
gives you the address of the std::vector
object, not the address of the data it holds. &something.begin()
gives you the address of the iterator returned by begin()
(as the compiler warns, this is not technically allowed because something.begin()
is an rvalue expression, so its address cannot be taken).
Assuming the container has at least one element in it, you need to get the address of the initial element of the container, which you can get via
&something[0]
or&something.front()
(the address of the element at index 0), or&*something.begin()
(the address of the element pointed to by the iterator returned bybegin()
).
In C++11, a new member function was added to std::vector
: data()
. This member function returns the address of the initial element in the container, just like &something.front()
. The advantage of this member function is that it is okay to call it even if the container is empty.
Get pointer to raw data in set like &(vector[0])
No, this is not necessarily possible. The C++ ISO standard explicitly guarantees contiguous storage of elements in a std::vector
, so you can safely take the address of the first element and then use that pointer as if you were pointing at a raw array. Other containers in the standard library do not have this guarantee.
The reason for this is to efficiently support most operations on a std::set
, the implementation needs to use complex data structures like balanced binary search trees to store and organize the data. These structures are inherently nonlinear and require nodes to be allocated and linked together. Efficiently getting this to work with the elements in a flat array would be difficult, if not impossible, in the time constraints laid out by the standard (amortized O(log n) for most operations.)
EDIT: In response to your question - there is no way to build a std::vector
from a std::set
without some code somewhere iterating over the set and copying the elements over. You can do this without explicitly using any loops yourself by using the std::vector
range constructor:
std::vector<T> vec(mySet.begin(), mySet.end());
Hope this helps!
Get raw data pointer from empty std::vector
Just perform the check inside a conditional operator:
int const * a = v.empty() ? NULL : &v[0];
This has the added benefit over data()
that you can check from the pointer itself whether the vector was empty: if it was, a
is null.
Using std::vector as view on to raw memory
The problem is that std::vector
has to make a copy of the elements from the array you initialize it with as it has the ownership of the objects it contains.
To avoid this, you can use a slice object for an array (i.e., similar to what std::string_view
is to std::string
). You could write your own array_view
class template implementation whose instances are constructed by taking a raw pointer to an array's first element and the array length:
#include <cstdint>
template<typename T>
class array_view {
T* ptr_;
std::size_t len_;
public:
array_view(T* ptr, std::size_t len) noexcept: ptr_{ptr}, len_{len} {}
T& operator[](int i) noexcept { return ptr_[i]; }
T const& operator[](int i) const noexcept { return ptr_[i]; }
auto size() const noexcept { return len_; }
auto begin() noexcept { return ptr_; }
auto end() noexcept { return ptr_ + len_; }
};
array_view
doesn't store an array; it just holds a pointer to the beginning of the array and the length of that array. Therefore, array_view
objects are cheap to construct and to copy.
Since array_view
provides the begin()
and end()
member functions, you can use the standard library algorithms (e.g., std::sort
, std::find
, std::lower_bound
, etc.) on it:
#define LEN 5
auto main() -> int {
int arr[LEN] = {4, 5, 1, 2, 3};
array_view<int> av(arr, LEN);
std::sort(av.begin(), av.end());
for (auto const& val: av)
std::cout << val << ' ';
std::cout << '\n';
}
Output:
1 2 3 4 5
Use std::span
(or gsl::span
) instead
The implementation above exposes the concept behind slice objects. However, since C++20 you can directly use std::span
instead. In any case, you can use gsl::span
since C++14.
Raw pointer, smart pointer or std::vector for low-level container data in C++
I would use std::vector
because it solves memory allocation, deallocation, indexing, copying, etc.. Unless you will be using "millions" of matrices at the same time, the extra member (capacity
) is probably not relevant.
In any case, optimizing the library for speed is the last thing you want to do -- after you can test the actual speed of your initial implementation. Then you can decide if it is worth spending time to effectively duplicate std::vector
functionality with your own implementation.
Is accessing the raw pointer after std::vector::reserve safe?
No, it is not safe.
After a reserve()
, the vector is guaranteed not to reallocate the storage until the capacity()
is reached.
However, the standard doesn't say what the vector implementation can do with the storage between size()
and capacity()
. Perhaps it can be used for some internal data - who knows? Perhaps the address space is just reserved and not mapped to actual RAM?
Accessing elements outside of [0..size) is undefined behavior. There could be some hardware check for that.
Is it possible to get a raw pointer to std::vector unsigned int data?
So two things:
You can access the contiguous memory of a vector with
std::vector::data()
or&vec.front()
.If you do that in the code shown above, you'll be returning a pointer to data that disappears when the function returns (the vector's destructor will run, and the data will be freed).
Related Topics
How Many and Which Are the Uses of "Const" in C++
How to Get a Process Handle by Its Name in C++
Which C I/O Library Should Be Used in C++ Code
Initializing a Two Dimensional Std::Vector
How to Check If a C++ String Is an Int
C++: Constructor Initializer For Arrays
What Are the Advantages of Using Nullptr
Semantics of Flags on Basic_Ios
Create Wcf Service For Unmanaged C++ Clients
C/C++ Include Header File Order
What Is More Efficient? Using Pow to Square or Just Multiply It With Itself
What New Capabilities Do User-Defined Literals Add to C++
Split a String into Words by Multiple Delimiters
How to Declare a Templated Struct/Class as a Friend
Why Doesn't C++ Use Std::Nested_Exception to Allow Throwing from Destructor