3

I have a problem when trying to delete a vector of pointers:

std::vector<float*> *v;

v = new std::vector<float*>;
v->assign(2, new float[2]);

for (int i = 0; i < 2; ++i)
{
    delete[] v->at(i);
}
delete v;

I'm deleting each element from the whole vector, but I still get an assert. Can you please tell me what I'm doing wrong?

Thank you in advance.

2
  • What assert are you getting? Commented Sep 20, 2013 at 9:45
  • This is the assert: Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) Commented Sep 20, 2013 at 9:48

3 Answers 3

5

This doesn't do what you think it does:

v->assign(2, new float[2]);

One array of size 2 is allocated, then two pointers to it are stored in the vector. When you delete, the same pointer is deleted twice.

If you want a multidimensional array, you could try std::vector< std::array< float, 2 > >. Doing new and delete yourself are a code smell. (The same goes for new vector …; that is probably not what you really want.)

Sign up to request clarification or add additional context in comments.

3 Comments

the new vector is not making a pointer to the std::vector?
It is, but why do you need a pointer to a vector and not just a vector?
@user1917028: C++ tends to prefer value semantics; so you should have a really good reason to create a raw pointer to the vector. Assuming that you really want to do that, you may consider using smart pointers like std::shared_ptr or std::unique_ptr.
1

THe v->assign(2, new float[2]) does the same as :

float *f = new float[2];
for(int i = 0; i < 2; i++)
   v->push_back(f);

of course, that's MOST likely not what you want - you probably want:

for(int i = 0; i < 2; i++)
{
   float *f = new float[2];
   v->push_back(f);
}

And using new on vector is just plain wrong - just use a plain vector. Inside it, put a vector<float> - or, if you just want two elements every time, use something like:

struct f2 { float a; float b; };
vector<struct f2> v;

Comments

1

In general, having raw owning pointers is not a good idea (unless in special cases, like when you are defining some custom high-performance highly-specialized data structure).

In your code - unless you are in special cases - there should be no explicit calls to new and delete, in modern C++11/14.

Your code sample style seems more like Java and other garbage-collection-based reference-semantics-based languages style. Instead, C++ tends to prefer value semantics (e.g. prefer: MyClass x; to MyClass * px = new MyClass();, and if you really need some owning pointer, use smart pointers like std::shared_ptr or std::unique_ptr):

// Your original code:
//
//   std::vector<float*> *v;
//   v = new std::vector<float*>;
//
// Not good, since:
// 
// 1. You have a std::vector of owning pointers
//    (std::vector<float *>)
//
// 2. You have a raw owning pointer for the containing std::vector itself
//    (v = new std::vector<....>)
//

A more modern and correct way of writing your code can be using a vector of vectors (instead of a vector of raw owning pointers float*):

//
// Vector of vectors (i.e. 2D matrix), allocated on the stack
// Note: no raw owning pointers here.
//
vector<vector<float>> v;

Then you can use use std::vector::push_back() or some other std::vector methods to populate the vector.


As a more high-performance and less-overhead alternative for a 2D matrix, you could use a single 1D std::vector, and linearize the content of the 2D matrix in a single 1D contiguous vector, of size Rows * Columns, e.g.:

vector<float> matrix;
matrix.resize( Rows * Columns );

And to access element at position (rowIndex, columnIndex), you can use a formula like this (if you store matrix elements row-wise, i.e. row#1, row#2, ..., row#N):

indexInVector = columnIndex + rowIndex * Columns;

All this can be nicely wrapped in a class template template <typename T> class Matrix {...};, with proper methods to read and write matrix elements, and the containing std::vector<T> as data member.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.