Creando dinámicamente std :: vector // creando un puntero a un vector

I am new so I more than likely missing something key.

I am using std::vector to store data from a ReadFile operation.

Currently I have a structure called READBUFF that contains a vector of byte. READBUFF is then instantiated via a private type in a class called Reader.

class Reader{
public:
void Read();
typedef struct {
std::vector<byte> buffer;
} READBUFF;

private:
READBUFF readBuffer;
}

Within Read() I currently resize the array to my desired size as the default allocator creates a really large vector [4292060576]

void Reader::Read()
{
readBuffer.buffer.resize(8192);
}

This all works fine, but then I got to thinking I'd rather dynamically NEW the vector inline so I control the allocation management of the pointer. I changed buffer to be: std::vector* buffer. When I try to do the following buffer is not set to a new buffer. It's clear from the debugger that it is not initialized.

void Reader::Read()
{
 key.buffer =  new std::vector<byte>(bufferSize);
}

So then I tried, but this behaves the same as above.

void Reader::Read()
{
std::vector<byte> *pvector = new std::vector<byte>(8192);
key.buffer = pvector;
}

Main first question is why doesn't this work? Why can't I assign the buffer pointer to valid pointer? Also how do I define the size of the inline allocation vs. having to resize?

My ultimate goal is to "new up" buffers and then store them in a deque. Right now I am doing this to reuse the above buffer, but I am in essence copying the buffer into another new buffer when all I want is to store a pointer to the original buffer that was created.

 std::vector<byte> newBuffer(pKey->buffer);
 pKey->ptrFileReader->getBuffer()->Enqueue(newBuffer);

Thanks in advance. I realize as I post this that I missing something fundamental but I am at a loss.

preguntado el 27 de agosto de 11 a las 18:08

What? The default allocator creates a vector of 4 giga elements? Please tell me what compiler you are using, so I can stay away from it. -

Allocating vectors dynamically is a really bad idea. Just don't do it. -

'default allocator creates a really large vector'. Default allocator does no such thing, perhaps you mean the default constructor, but that creates a zero size vector. key.buffer = new std::vector<byte>(bufferSize); will create a vector of size bufferSize and assign pointer to it to key.buffer. You say it doesn't but it does. 'Main first question', you do it exactly as you are trying to do it, any of the methods you've posted will work. There's clearly something wrong with the way you are interpreting what you are seeing, but I have no idea what it is. Your code is fine, honestly. -

@R. Martinho Fernandes. I am using MSVC2010. I misread the watch window as "allocated size" ? key.buffer.size() 4288718240, prior to doing any allocation. I was looking at process viewer and didn't see my wokring set change, hence the confusion. -

2 Respuestas

No deberías estar usando new in this case. It causes you to have to manage the memory manually, which is nunca something you should want to do for many reasons1. You said you want to manage the lifetime of the vector by using new; in reality, the lifetime of the vector is already managed because it's the same as the object that holds it. So the lifetime of that vector is the lifetime of the instance of your Reader class.

To set the size of the vector before it gets constructed, you'll have to make a constructor for READBUFF:

// inside the READBUFF struct (assuming you're using a normal variable, not a pointer)
READBUFF() { } // default constructor
READBUFF(int size) : buffer(size) { } // immediately sets buffer's size to the argument 

and use an initialization list in Readerconstructor de:

// inside the Reader class
Reader() : readBuffer(8092) { }

Which will set the readBuffer.buffer's size to 8092.


Si really want to use new just for learning:

key.buffer =  new std::vector<byte>(bufferSize);

This will work fine, but you shouldn't be doing it in the Read function, you should be doing it in the object's constructor. That way any member function can use it without having to check if it's NULL.

as the default allocator creates a really large vector [4292060576]

No, it doesn't (if it did, you could have one vector on your entire computer and probably your computer would crash). It incrementally resizes the storage up when you add things and exceed the capacity. Using resize like you are doing is still good though, because instead of allocating a small one, filling it, allocating a bigger one and copying everything over, filling it, allocating a bigger one and copying everything over, etc. you are just allocating the size you need once, which is much faster.

1 Algunas razones son:

  1. You have to make sure to allocate it before anyone else uses it, where with a normal member variable it's done automatically before your object has a chance to use it.
  2. You have to remember to delete it in the destructor.
  3. If you don't do the above 2 things, you have either a segfault or a memory leak.

Respondido 28 ago 11, 06:08

@celavek whoops thanks, it's amazing what a difference 3 letters can make. - Seth Carnegie

There is nothing wrong with managing your own memory. As a programmer, you should be aware at every instance of the program what memory you have and what not. Not having already allocated some memory is a very newbie mistake. If you forget to delete that means you have lost track of your own program. Bad sign. (If you are afraid of memory, you can always switch to java) - Shahbaz

@Shahbaz "Not having already allocated some memory is a very newbie mistake" yeah, and the nature of this question prompted me to say it. And no, there is nothing wrong with managing your own memory, but why complicate things with manual memory management when you could have it automatically managed for you? You don't gain anything from dynamic memory in this case. - Seth Carnegie

@seth carnegie. In the case of this question, of course. I mean, you are using vectors, you might as well use vectors of vectors, right? ;) - Shahbaz

@Seth Carnegie. Thanks man. You hit on the core of my question, which was really about memory management. I got rat holed by misunderstanding what the immediate window was telling me in VS. I am all for the non "newing" route for vectors. I am coming from the .NET world as well as old C (10 years) ago and as Shahbaz has a point about "being afraid of memory" - my goal was to better understand the pros and cons here. I get it now. - Eric Schmidt

I think you may be misinterpreting the result of calling max_size() on a vector:

#include <vector>
#include <iostream>

int main() {
  std::cout << std::vector<char>().max_size() << std::endl;
  std::cout << std::vector<char>::size_type(~0) << std::endl;
}

This program prints the maximum possible size of the vector, not the current size. size() por otra parte print the current size (ignoring anything that's been reserved).

Respondido 27 ago 11, 22:08

thanks as i noted above i mis-read the debug/immediate window - prior to actual allocation or resize. - Eric Schmidt

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.