Results 1 to 6 of 6

Thread: Defining a two dimensional QVector class (Q2DDoubleVector)

  1. #1
    Join Date
    Jun 2011
    Location
    Delft, Netherlands
    Posts
    11
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Defining a two dimensional QVector class (Q2DDoubleVector)

    Hello,

    I am trying to build a class, that can hold a resizable two
    dimensional array of double values.

    I need this, to hold a matrix of 1e6 rows and 5 or more colums of real-time data.
    When the data aquisition is running I want to avoid to allocate memory, because that can be slow.

    But I want to be able to change the exact number of rows and columns in a configuration file (and
    in a menu option, when the aquisition is not running), and therefore I need a dynamic array.

    The following code crashes:

    Qt Code:
    1. class Q2DDoubleVector : public QVector< QVector<double> > // Overloading Class QVector to allow for 2 dimensional vectors.
    2. {
    3. public:
    4. // constructor
    5. Q2DDoubleVector() : QVector< QVector<double> >(){}
    6. // methods
    7. // matrix resize
    8. void mresize(int rows, int columns);
    9. // destructor
    10. virtual ~Q2DDoubleVector() {}
    11. };
    12.  
    13. void Q2DDoubleVector::mresize(int rows, int columns)
    14. {
    15. this->resize(rows);
    16. for(int r=0; r<rows; r++) {
    17. this[r].resize(columns);
    18. }
    19. }
    20.  
    21. Q2DDoubleVector matrix;
    22. matrix.mresize(ROWS, COLS);
    To copy to clipboard, switch view to plain text mode 

    If I do it in a very similar way, it doesn't crash:

    Qt Code:
    1. QVector<QVector <double> > matrix;
    2.  
    3. matrix.resize(ROWS);
    4. for(int r=0; r < ROWS; r++) {
    5. matrix[r].resize(COLS);
    6. }
    To copy to clipboard, switch view to plain text mode 

    Why does the first approach not work?

    I don't want to implement the resize loop for each 2D matrix, that I use again.

    You can download both projects (the example that works (ArrayTest) and
    the example that doesn't work (ArrayTest2) from the following URL:
    http://db.tt/IUWpBCnY

    Any hints welcome.

    Actually, I was using Delphi in the past, and with Delphi this was very easy:
    Qt Code:
    1. var Matrix: array of array of Double;
    2. begin
    3. SetLength(Matrix, 10, 20)
    4. end;
    To copy to clipboard, switch view to plain text mode 

    Best regards:

    Uwe Fechner

    I am using Ubuntu 11.04 32 bit and QT 4.7.2 .
    Last edited by ufechner; 25th September 2011 at 23:02.

  2. #2
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Defining a two dimensional QVector class (Q2DDoubleVector)

    If I do it in a very similar way, it doesn't crash:
    There is one "small" difference:
    Qt Code:
    1. (1) this[r].resize(columns);
    2. vs.
    3. (2) matrix[r].resize(COLS);
    To copy to clipboard, switch view to plain text mode 
    Line (1) does not call "operator []" on this pointer like (2). Its equivalent to
    Qt Code:
    1. *(this+r).resize(columns);
    To copy to clipboard, switch view to plain text mode 
    Can you see the problem ? Its like you want to access an array of objects using index r, where this should point to the first element. Obviously this array does not exists, so your program crashes.
    You can fix this by changing (1) to:
    Qt Code:
    1. (*this)[r].resize(columns);
    To copy to clipboard, switch view to plain text mode 
    IMHO you should not subclass a QVector, it does not have a virtual destructor. Better use composition instead.

    ----
    edit:
    I've made a simple example to show this pointer arithmetic "magic":
    Qt Code:
    1. #include <QDebug>
    2.  
    3. class Test{
    4. public:
    5. Test(){
    6.  
    7. }
    8. void check(){
    9. qDebug() << "this is" << x << ", next is:" << this[1].x;
    10. }
    11. int x;
    12. };
    13.  
    14. int main(){
    15. Test x[5];
    16. for( int i=0 ; i<5 ; ++i ){
    17. x[i].x = i;
    18. }
    19. for( int i=0 ; i<4 ; ++i ){
    20. x[i].check();
    21. }
    22. }
    23. // outputs:
    24. // this is 0 , next is: 1
    25. // this is 1 , next is: 2
    26. // this is 2 , next is: 3
    27. // this is 3 , next is: 4
    To copy to clipboard, switch view to plain text mode 
    We create an array of 5 objects, assigned unique, ordered values. In method "check" we can access next element in that array, using pointer arithmetic ( this[1] = *(this+1) = next object in array ).
    Don't use it in "real" code, its just for fun
    Last edited by stampede; 25th September 2011 at 22:56.

  3. #3
    Join Date
    Jun 2011
    Location
    Delft, Netherlands
    Posts
    11
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Defining a two dimensional QVector class (Q2DDoubleVector)

    Hello,
    I tried your suggested change:
    Qt Code:
    1. (*this)[r].resize(columns);
    To copy to clipboard, switch view to plain text mode 

    but this didn't help:

    The code still crashes.

    Regards:

    Uwe

  4. #4
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Defining a two dimensional QVector class (Q2DDoubleVector)

    So use debugger to check where exactly it crashes, I've just tested your class with following code:
    Qt Code:
    1. class Q2DDoubleVector : public QVector< QVector<double> > // Overloading Class QVector to allow for 2 dimensional vectors.
    2. {
    3. public:
    4. // constructor
    5. Q2DDoubleVector() : QVector< QVector<double> >(){}
    6. // methods
    7. // matrix resize
    8. void mresize(int rows, int columns);
    9. // destructor
    10. virtual ~Q2DDoubleVector() {}
    11. };
    12.  
    13. void Q2DDoubleVector::mresize(int rows, int columns)
    14. {
    15. this->resize(rows);
    16. for(int r=0; r<rows; r++) {
    17. (*this)[r].resize(columns);
    18. }
    19. }
    20. // in main() :
    21. Q2DDoubleVector m;
    22. int row = 5, col = 6;
    23. m.mresize(row,col);
    24. for( int i=0 ; i<row ; ++i )
    25. for( int j=0 ; j<col ; ++j ){
    26. m[i][j] = (i+1)*(j+1);
    27. qDebug() << m[i][j];
    28. }
    To copy to clipboard, switch view to plain text mode 
    This code executed without a crash. Make sure you rebuild the project too.

  5. #5
    Join Date
    Jun 2011
    Location
    Delft, Netherlands
    Posts
    11
    Qt products
    Qt4
    Platforms
    Unix/X11

    Smile Re: Defining a two dimensional QVector class (Q2DDoubleVector)

    Hello,
    I tried again, and now it works fine.

    Qt Code:
    1. class Q2DDoubleVector : public QVector< QVector<double> > // Overloading Class QVector to allow for 2 dimensional vectors.
    2. {
    3. public:
    4. // constructor
    5. Q2DDoubleVector() : QVector< QVector<double> >(){}
    6. // methods
    7. // matrix resize
    8. void mresize(int rows, int columns);
    9. // destructor
    10. virtual ~Q2DDoubleVector() {}
    11. };
    12.  
    13. void Q2DDoubleVector::mresize(int rows, int columns)
    14. {
    15. this->resize(rows);
    16. for(int r=0; r<rows; r++) {
    17. (*this)[r].resize(columns);
    18. }
    19. }
    20.  
    21. Q2DDoubleVector matrix;
    22. matrix.mresize(ROWS, COLS);
    To copy to clipboard, switch view to plain text mode 

    Thank's a lot for your help!

    Uwe Fechner

  6. #6
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Defining a two dimensional QVector class (Q2DDoubleVector)

    Great, no problem.
    But I think you should really consider composition in your code:
    Qt Code:
    1. class Q2DDoubleVector{
    2. public:
    3. Q2DDoubleVector(){}
    4. void mresize(int rows, int columns);
    5. virtual ~Q2DDoubleVector() {}
    6. protected:
    7. QVector< QVector<double> > _data;
    8. };
    9.  
    10. void Q2DDoubleVector::mresize(int rows, int columns)
    11. {
    12. _data.resize(rows);
    13. for(int r=0; r<rows; r++) {
    14. _data[r].resize(columns);
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 
    I think this code is much simpler.

Similar Threads

  1. Replies: 5
    Last Post: 2nd September 2011, 23:11
  2. Replies: 1
    Last Post: 5th February 2011, 03:04
  3. use QVector as 2 dimensional Array
    By umulingu in forum Qt Programming
    Replies: 3
    Last Post: 1st January 2010, 12:31
  4. How to implement one-dimensional zoom
    By d_stranz in forum Qwt
    Replies: 0
    Last Post: 7th November 2008, 17:46
  5. Multi Dimensional QList
    By aamer4yu in forum Qt Programming
    Replies: 5
    Last Post: 2nd April 2007, 06:46

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.