0

My understanding is that you can access the data in a std::vector using pointers. For example:

char *ptr;
std::vector<char> v1 {'A', 'B', 'C'};
ptr = &v1[0]
if (*(ptr+1) == 'B')
    std::cout << "Addressing via pointer works\n";

How about loading a std::vector directly? For example:

std::vector<char> v2;
v2.reserve(3); // allocate memory in the vector 
ptr = &v2[0]
*ptr = 'A';
*(ptr+1) = 'B';
*(ptr+2) = 'C';
if (v2[1] == 'B')
    std::cout << "Data is in vector buffer!\n";

but

if (!v2.size())
    std::cout << "But the vector doesn't know about it!\n";

My question: Is there any way to tell the v2 vector that its internal memory buffer is loaded with data? This would be useful when you want to use a std::vector to hold data that is sourced from a file stream.

I look forward to your comments.

Mark S.
  • 27
  • 7
  • 3
    `reserve` doesn't change size, only capacity. For the rest of the code to be valid replace `reserve` with `resize`. – Maxim Egorushkin Jun 02 '20 at 17:15
  • What you are doing is modify memory owned by the vector without telling it what you have done. – Mansoor Jun 02 '20 at 17:16
  • why do you think that accessing the vector via the pointer `ptr` is more efficient? – bolov Jun 02 '20 at 17:16
  • Assigning to memory outside of the `vector`'s size, like you're doing here, is undefined behavior. For specific implementations you can verify whether it's fine or not (it *probably* is but that's no guarantee that the compiler or stdlib version next year will be fine). And then there's the issue that increasing the size of the `std::vector` will default initialize the elements, so you'll have to go back and reset them to the value you want. Either make the vector using the sized constructor `std::vector v2(3)` and then assign, or use list initialization. – JohnFilleau Jun 02 '20 at 17:17
  • https://stackoverflow.com/questions/7397768/choice-between-vectorresize-and-vectorreserve – Mat Jun 02 '20 at 17:17
  • 1
    See example how to load a file into a vector: https://en.cppreference.com/w/cpp/iterator/istreambuf_iterator – Maxim Egorushkin Jun 02 '20 at 17:18
  • To do something like you want with a lazy resizing you'd have to specify a custom "lazy" allocator so that the elements aren't default initialized. But still, just use list initialization. https://en.cppreference.com/w/cpp/memory/allocator – JohnFilleau Jun 02 '20 at 17:19
  • @bolov The reason for accessing the vector via a pointer is that some lower level file i/o functions require a pointer to a buffer. (e.g. ifsteam::read) Now, I have to read the file into an allocated char buffer, and then copy it to the vector. – Mark S. Jun 03 '20 at 03:52
  • @Mansoor Exactly. My question is - Since it is possible to resize the vector, is it also possible to modify the vectors memory and have the vector recognize that inserted data? – Mark S. Jun 03 '20 at 03:59
  • @JohnFilleau Good point about the default initialization when a vector is resized. Unfortunately, the std::vector is a private class member that is used post creation so the sized constructor or list initialization doesn't help. – Mark S. Jun 03 '20 at 04:05

1 Answers1

1

Is there any way to tell the v2 vector that its internal memory buffer is loaded with data?

No.

The behaviour of your second example is undefined.

This would be useful when you want to use a std::vector to hold data that is sourced from a file stream.

You can read a file into vector like this:

std::vector<char> v3(count);
ifs.read(v3.data(), count);

Or like this:

using It = std::istreambuf_iterator<char>;
std::vector<char> v4(It{ifs}, It{});
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Thanks for your examples. In my case, the std::vector is already created as a buffer in the class's private space. Both of the examples above make use of the std::vector constructor. How would you load an already existing std::vector with the ifs stream? – Mark S. Jun 03 '20 at 03:39
  • What I am doing now is loading the file content into a char buffer[] sized by the stream buffer size into, and then copying it into the existing vector. – Mark S. Jun 03 '20 at 04:10