2

I get the following error when I try to run this code in Visual Studio 2010:

Unhandled exception at 0x012c23d3 in matrix.exe: 0xC0000005: Access violation reading location 0xccccccd0.

Here's the code:

#include <vector> using namespace std; class matrix : public vector<vector<char>> { public: matrix(int x, int y) { this->resize(x); for (int i = 0; i < y; ++i) { this[i].resize(y); } } }; void main() { matrix mat(10, 10); } 

I'm trying to create a matrix class that expands on the vector<vector<char>> type by adding built-in matrix manipulation functions. However, I can't get this constructor to run properly.

Thanks for your help.

7
  • 7
    Ouch. Don't inherit publicly standard container. They don't have virtual destructor, you could end up in very ugly situations... Commented May 22, 2013 at 18:24
  • don't you want i < x in your loop? Commented May 22, 2013 at 18:25
  • Your constructor first resizes the object to be able to contain 10 vectors, and then resizes each of those to be able to contain 10 chars... however resize doesn't create those elements, it only makes room for them. You're trying to resize the child vectors that have not yet been created, no? Commented May 22, 2013 at 18:30
  • Okay--I see what you mean about the child vectors not being created yet. For some reason I couldn't assign this[i] to a new vector. Commented May 22, 2013 at 18:36
  • You couldn't assign this[i] to a new vector because this is a vector of vectors, and new vector creates a pointer to a vector. Commented May 22, 2013 at 18:37

4 Answers 4

3

First, don't inherit publicly from standard containers: They aren't meant for it, having no virtual destructor. Even if you never intend for your derivation to be deleted by base class pointer, someone will come along and do it years from now, not realizing the pitfall. Inheriting from standard containers protectedly or privately is fine because you can't attempt to polymorphically destroy your child.

Then your problem is twofold: i < y instead of i < x in your loop condition and this[i] instead of (*this)[i] which would cause it to use the parent class operator[] rather than the builtin [] that operators on arrays and pointers.

BUT your entire constructor could be done away:

matrix(int x, int y) : vector<vector<char> >(x, vector<char>(y)) { } 
Sign up to request clarification or add additional context in comments.

8 Comments

mmm. I liked my version better (with the typedef). Anyways, I've blasted it for a proper, non-inheriting demo
Strictly speaking, it's not improper to derive from classes that do not have a virtual destructor as long as the derived classes are never handled via polymorphic means.
Then your problem is i < y instead of i < x in your loop condition. -- that's a potential problem, but not a problem in his immediate case since for his failing test, x == y == 10.
Thanks for showing me how to do the constructor correctly. I'll try some of these suggestions for creating a better class that doesn't use standard containers.
I am agreed with @mah that's not the actual problem... The actual problem is that this[i] is not the vector in position i but the pointer address + i bytes
|
3

Besides all other recommendations your problem is on the line:

this[i].resize(y); 

Since it is not doing what you want. It is moving the pointer of this by i bytes. Since you want to access the [] operator you need to dereference the pointer:

(*this)[i].resize(y); 

5 Comments

I noticed the discrepancy and deleted my comment as you were posting yours. However something doesn't quite look right to me about your suggestion... perhaps (*this)[i].resize(y) is more correct?
@mah yeah I noticed and deleted my comment too. Oops you are right... transcription typo :) Thanks.. just edited it.
Oh--wow. I had tried *this[i].resize(y) and it wouldn't compile, but your recommendation of (*this)[i].resize(y) works fine. Is this because it's interpreting the former as *(this[i].resize(y))?
@Praetorius I think the compiler would interpret *this[i].resize(y) as (*this[i]).resize(y) and wont compile since this[i] is not a vector (or even an object)
+1 you should consider this->operator[](i) in readability edge cases like this. Of course, better yet: use at(i) :) (or not abuse inheritance in the first place...)
3

I suggest rewriting this as follows: http://ideone.com/mzsE8e

#include <vector> #include <iostream> template <typename T> using matrix = std::vector<std::vector<T>>; template <typename T> matrix<T> make_matrix(size_t x, size_t y) { return { x, typename matrix<T>::value_type(y) }; } int main() { auto mat = make_matrix<char>(3, 5); // for demonstration only: for (auto& row : mat) { for (auto& cel : row) std::cout << (int) cel << " "; std::cout << "\n"; } } 

Comments

0

Try this instead:

class matrix : public vector< vector< char > > { public: matrix(int x, int y) { vector< char > _val(y, 0); this->resize(x, _val); } }; 

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.