-2

I have a vector of chars:

vector<char> bytesv;

I push 1024 chars to this vector in a loop (not important to the context) using push_back(char):

bytesv.push_back(c);

I know this vector has an exact value of 1024. It indeeds print 1024 when doing the following:

cout << bytesv.size() << "\n";

What I am trying to do: I need to transform this vector into a char array (char[]) of the same length and elements as the vector. I do the following:

char* bytes = &bytesv[0];

The problem: But when I print the size of this array, it prints 4, so the size is not what I expected:

cout << sizeof(bytes) << "\n";

Full code:

vector<char> bytesv;

for (char c : charr) { // Not important, there are 1024 chars in this array
    bytesv.push_back(c);
}
cout << bytesv.size() << "\n";
char* bytes = &bytesv[0];
cout << sizeof(bytes) << "\n";

Prints:

1024
4

This obviously has to do with the fact that bytes is actually a char*, not really an array AFAIK. The question: How can I safely transfer all the vector's contents into an array, then?

Momo
  • 3,542
  • 4
  • 21
  • 34
  • Possible duplicate of [How to convert vector to array C++](http://stackoverflow.com/questions/2923272/how-to-convert-vector-to-array-c) – Shadow Oct 29 '15 at 02:36
  • *I need to transform this vector into a char array (char[]) of the same length and elements as the vector.* Why? A `vector` internally *is* a char array that is just wrapped. Just call `vector::data()` to access the array. – PaulMcKenzie Oct 29 '15 at 03:01

6 Answers6

3

How can I safely transfer all the vector's contents into an array, then?

  1. Allocate the required memory by using dynamic memory allocation.

    size_t size = bytesv.size();
    char* char_array = new char[size];
    
  2. Copy the elements from the vector to the array.

    for ( size_t i = 0; i < size; ++i )
       char_array[i] = bytesv[i];
    
  3. Make sure you deallocate the memory after you are done using it.

    delete [] char_array;
    

Having said, that I realized that you mentioned in a comment,

My ultimate goal is to save these bytes to a file, using fstream, which requires an array of chars as far as I am concerned.

You don't need to copy the contents of the vector to an array to save them to an fstream. The contents of a std::vector are guaranteed to be in contiguous memory. You can just use:

outStream.write(bytesv.data(), bytesv.size());
R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

sizeof(bytes) is the size of the pointer, not what it points to. Also,

char* bytes = &bytesv[0];

Doesn't transfer anything to an array, all you've done is saved a pointer to the beginning of the underlying array in std::vector.

To correctly move the data to an array you'll need to dynamically allocate an array. But the question is why would you do that? You already have a vector. It's like an array but about a billion times better.

Michael Albers
  • 3,721
  • 3
  • 21
  • 32
  • My ultimate goal is to save these bytes to a file, using fstream, which requires an array of chars as far as I am concerned. – Momo Oct 29 '15 at 02:37
  • 2
    @Momo Then you should just be able to use your "bytes" variable as you have it coded and get the length from the vector. – Michael Albers Oct 29 '15 at 02:38
  • "You already have a vector. It's like an array but about a billion times better." +1 – brettwhiteman Oct 29 '15 at 02:56
1

How can I safely transfer all the vector's contents into an array, then?

There's no need to "transfer" (i.e. copy). You can access the vector's underlying storage as an array by using the data method.

char* arr = bytesv.data();

http://en.cppreference.com/w/cpp/container/vector/data

bytes is actually a char*, not really an array

The char* is not an array but a pointer to the first value in the array. You can get the number of elements in the array from bytesv.size()

brettwhiteman
  • 4,210
  • 2
  • 29
  • 38
  • The question OP asked was to " transfer all the vector's contents into an array" - not to "access the vector like an array". So copy operation IS necessary. – Constantin Oct 29 '15 at 03:03
  • 1
    @Constantin, not strictly true since OP mentioned in another comment of the ultimate goal of writing the data to a file with `fstream`. – GreatAndPowerfulOz Oct 29 '15 at 03:05
  • @Constantin given that the OP tried using this `char* bytes = &bytesv[0];` obviously he doesn't actually need a copy. He just wants to access the data in an array form. – brettwhiteman Oct 29 '15 at 03:15
  • @developerbmw No, that's not obvious as the question states something else. He's a beginner so it's more likely, that he doesn't understand the basics of memory management (and that a copy operation is necessary to "transfer" data from a `vector` to an array). His question was not: How to write a `vector` to a file using `fstream`: You didn't answer the question he raised, but a specific problem which is not part of the question - this is irritating for anyone who finds this question in the future if they want to do what OP has asked in his initially question. – Constantin Oct 29 '15 at 03:33
0

That's because the sizeof any pointer is 4 (on a 32 bit target). What

char* bytes = &bytesv[0];

is giving you is a pointer to the first element, not, necessarily, an array of chars.

now if you used:

char (*bytes)[1024] = (char (*)[1024])&v[0];
std::cout << sizeof(bytes) << " " << sizeof(*bytes);

that would give you a pointer to a 'char[1024]' array.

GreatAndPowerfulOz
  • 1,767
  • 13
  • 19
0

sizeof(bytes) is always 4 because *bytes is a pointer and you are using a machine that uses 4-byte pointers.

You already know that you have 1024 bytes; just use that knowledge.

vacuumhead
  • 479
  • 1
  • 6
  • 16
0

First of all: you need to copy the content of the vector to the array - otherwise you can't access elements of your array, when the vector is gone. So you need to allocate memory to your array (not just defining a pointer).

char* bytes = new char[bytesv.size()];
for (size_t i = 0; i < bytesv.size(); ++i) {
  bytes [i] = bytesv.at(i);
}
//...
delete[] bytes;

Secondly sizeof() doesn't do what you expect: its not reporting the length of an array, but the size of a type/pointer. In case of stack allocated arrays, it can be used as: sizeof(array)/sizeof(array[0]); to determine the size, but as sizeof() is a compile time operator it can't know the size of your dynamic allocated arrays or vectors.

If you use an array, you need to use a seperate variable to store the length of this array (alternatively you could use std::array instead).

#include <iostream>
#include <string>
#include <vector>

int main(int argc, char* argv[]){
  std::vector<uint8_t> bytesv = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
  size_t bytesLength = bytesv.size();
  char* bytes = new char[bytesLength];
  for (size_t i = 0; i < bytesv.size(); ++i) {
    bytes[i] = bytesv.at(i);
  }
  //...
  std::cout << bytesLength << std::endl;
  delete[] bytes;
  return 0;
}
Constantin
  • 8,721
  • 13
  • 75
  • 126