Results 1 to 17 of 17

Thread: How to get a pointer for 2D array of QVector?

  1. #1
    Join Date
    Sep 2012
    Posts
    7
    Thanks
    1

    Default How to get a pointer for 2D array of QVector?

    Hello All,

    1D and 2D arrays with QVector can be declared as follows:

    QVector< int > myA1D;
    QVector<QVector<int> > myA2D;

    and I can use them: myA1D[i] and myA2D[i][j].

    I need to get pointers of them because the pointers should be given to Fortran codes.

    For 1D, we can do....

    int *pA1D = myA1D.data();

    For 2D, How to get the pointer?

    int **pA2D = ????

    Could someone help me? Please!



    I could do it by using additional memory spaces (Not verified yet);

    QVector<QVector<int> > myA2D;
    QVector< int* > tempPtA2D;
    int **pA2D;

    - tempPt2D[0] = myA2D[0].data() ....;
    - pA2D = tempPt2D.data();
    - int aaa = pA2D[][];

    But it uses additional memory spaces, which I don't like.

    Please let me know good techniques or other libraries for me.
    - I would like to avoid "using new and delete to generate 2D array." (That's why I want to use QVector.)

    Thank you.

  2. #2
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    simply, you cannot. The data of QVector<QVector<int> > is not in a contiguous block.

    Your code is wrong as well.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  3. #3
    Join Date
    Sep 2012
    Posts
    7
    Thanks
    1

    Default Re: How to get a pointer for 2D array of QVector?

    Can you tell me which part is wrong?

    The following codes work:

    QVector<QVector<int> > test2D;

    test2D.resize(10);
    for(int i=0; i<10; ++i)
    {
    (test2D[i]).resize(5);
    }

    for(int i=0; i<10; ++i)
    for(int j=0; j<5; ++j) test2D[i][j] = 3*i+j;

  4. #4
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    This just doesn't make sense:
    Qt Code:
    1. QVector<QVector<int> > myA2D;
    2. QVector< int* > tempPtA2D;
    3. int **pA2D;
    4.  
    5. - tempPt2D[0] = myA2D[0].data() ....;
    6. - pA2D = tempPt2D.data();
    7. - int aaa = pA2D[][];
    To copy to clipboard, switch view to plain text mode 

    Can you tell me which part is wrong?

    The following codes work:

    QVector<QVector<int> > test2D;

    test2D.resize(10);
    for(int i=0; i<10; ++i)
    {
    (test2D[i]).resize(5);
    }

    for(int i=0; i<10; ++i)
    for(int j=0; j<5; ++j) test2D[i][j] = 3*i+j;
    yes, that 'works', but you cannot pass anything there to a fortran routine that expects a 2d array (int[][] for example).

    Also, please use code tags in future.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  5. #5
    Join Date
    Sep 2012
    Posts
    7
    Thanks
    1

    Default Re: How to get a pointer for 2D array of QVector?

    Back to my basic problem, I need to create 2D and 3D array, and need their pointers, which will be passed to fortran codes.
    I am looking for an easy way to create and clear memory spaces, not using new[] or delete[] by myself. (There are so many arrays in codes which I'm working on).

    Do you have any suggestion what kind of approaches or methods or libraries I could use?

    Thank you for your reply and comments.

  6. #6
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: How to get a pointer for 2D array of QVector?

    I suggest you read this StackOverflow question which addresses the problem.

    Ultimately there is a single memory allocation per array regardless of dimension count (it is not a an array of pointers to other blocks). You have to deal with column-major vs row-major differences and base index differences. Should be fairly easy to wrap into a basic class that automates the allocation/deallocation and index juggling but I'm sure that wheel has been invented before. What FORTRAN library are you interfacing with? Does it not have utility functions or guidance to help with this stuff?

    See also:
    http://arnholm.org/software/cppf77/c...m#Section3.5.3
    http://arnholm.org/software/cppf77/c...htm#Section6.3

  7. #7
    Join Date
    Sep 2012
    Posts
    7
    Thanks
    1

    Default Re: How to get a pointer for 2D array of QVector?

    I have long fortran source codes, whose subroutines will be called by C++ functions. The issues regarding "column-major vs row-major" might cause big headaches.

    Thank you for your info. and comments.

  8. #8
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    I'd be interested in how well this works:
    Qt Code:
    1. template<class T, unsigned int M, unsigned int N>
    2. class FortranMatrix
    3. {
    4. public:
    5. FortranMatrix()
    6. :array_(new T[M][N])
    7. {}
    8.  
    9. // cpp interface
    10. T& at(unsigned int x, unsigned int y)
    11. {
    12. return (array_)[x][y];
    13. }
    14.  
    15. // fortran interface - transpose it
    16. T& operator()(unsigned int x, unsigned int y)
    17. {
    18. return (array_)[y][x];
    19. }
    20.  
    21. //pass the matrix to a fortran method accepting a T*
    22. operator T*()
    23. {
    24. return &(*array_)[0];
    25. }
    26.  
    27. private:
    28. T (*array_)[N];
    29. };
    To copy to clipboard, switch view to plain text mode 

    I cant be bothered to get fortran, but doesn't this avoid all the copying that FMATRIX does in those links?
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  9. The following user says thank you to amleto for this useful post:

    tfmp (10th September 2012)

  10. #9
    Join Date
    Sep 2012
    Posts
    7
    Thanks
    1

    Default Re: How to get a pointer for 2D array of QVector?

    amleto, your idea is great. In C++, there is no problem, but I have no idea yet how to pass or apply your fortran interface (below)to Fortran:

    Qt Code:
    1. // fortran interface - transpose it
    2. T& operator()(unsigned int x, unsigned int y)
    3. {
    4. return (array_)[y][x];
    5. }
    To copy to clipboard, switch view to plain text mode 


    Added after 15 minutes:


    For 2D array, I want to use Boost library, which provides contiguous blocks for 2D and 3D arrays.

    For the array transfer, I tried the following way:
    - Generate "Column-major" memory space in C++, to facilitate the access from Fortran codes.
    - In C++, use an operator () to access the memory in [j][i] pattern.
    (My situation is: I wrote C++ codes, and have already-written Fortran codes using multi-dimension arrays.)
    - In C++, (i,j) should be used for [i][j], not directly using [i][j]. (It is easy for me now).
    - In Fortran, (i,j) is used (without any code modification).

    Here is the codes: ( I finally found "Code" tag. )

    // File: *.h
    Qt Code:
    1. /* Boost library. */
    2. #ifndef Q_MOC_RUN // To avoid an error regarding "Boost_JOIN "
    3. #include <boost/multi_array.hpp>
    4. #endif
    5.  
    6. typedef boost::multi_array<double, 2> btArrayDbl2D_type;
    7.  
    8. /*-----*
    9.   Double-type 2D array.
    10.   - In C/C++, use MATDBL2D(i=0..., j=0...), not A, not A[i][j].
    11.   - In Fortran, use A(i=1..., j=1...).
    12. *-----*/
    13. struct MATDBL2D
    14. {
    15. public:
    16. MATDBL2D() : szI_(0), szJ_(0) {}
    17. btArrayDbl2D_type A;
    18.  
    19. private:
    20. uint szI_, szJ_;
    21.  
    22. public:
    23. // "Column-major" memory storage is used herein to transfer data to Fortran codes: A[1][1],A[2][1],A[3][1],A[1][2]...
    24. // [Note] C++ uses a "Row-major" memory storage system: A[1][1],A[1][2],A[1][3],A[2][1]...
    25. void makeMem(uint szI, uint szJ)
    26. {
    27. szI_ = szI;
    28. szJ_ = szJ;
    29. A.resize(boost::extents[szJ_][szI_]); // "Column-major" memory storage.
    30. }
    31.  
    32. // For C++ interface.
    33. // - NEVER access directly to A[][], which contains data as "Column-major" memory storage.
    34. double & operator()(uint i, uint j) { return A[j][i]; }
    35. const double & operator()(uint i, uint j) const { return A[j][i]; }
    36.  
    37. uint szI() { return szI_;} // For C/C++ & // To pass its size to Fortran subroutines.
    38. uint szJ() { return szJ_;} // For C/C++ & // To pass its size to Fortran subroutines.
    39.  
    40. // For Fortran.
    41. // "A" will be directly accessed: ex) A(i,j): i,j=1-based number.
    42. // So "A" is set as a public variable.
    43. };
    To copy to clipboard, switch view to plain text mode 

    File: *.cpp
    Qt Code:
    1. int testFN()
    2. {
    3. int szI = 3;
    4. int szJ = 4;
    5. double b, X[3][4];
    6.  
    7. MATDBL2D A2D;
    8. A2D.makeMem(szI, szJ);
    9.  
    10. for(int i=0; i<szI; ++i){
    11. for(int j=0; j<szJ; ++j){
    12. X[i][j] = i*10. + j;
    13. A2D(i,j) = X[i][j];
    14. }
    15. }
    16.  
    17. // Testing......
    18. // 2D Sum.
    19. b=0.;
    20. b=A2D(0,0)+A2D(1,2)+A2D(2,0); // C++
    21.  
    22. b = 0.;
    23. int szFI = A2D.szI();
    24. int szFJ = A2D.szJ();
    25. SUM2D(A2D.A.data(), &b, &szFI, &szFJ); // Fortran subroutine.
    26. }
    To copy to clipboard, switch view to plain text mode 

    Fortran subroutine.
    Qt Code:
    1. subroutine SUM2D(a,b,I,J)
    2. real*8 a(I,J),b
    3. real*8 x(I,J)
    4. integer I,J
    5. do L=1,I
    6. do M=1,J
    7. x(L,M)=a(L,M)
    8. enddo
    9. enddo
    10. b=a(1,1)+a(2,3)+a(3,1)
    11. end subroutine
    To copy to clipboard, switch view to plain text mode 

    If you or someone have any better or easy methods or comments, please let me know.
    Thanks.
    Last edited by tfmp; 11th September 2012 at 20:58.

  11. #10
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    Quote Originally Posted by tfmp View Post
    amleto, your idea is great. In C++, there is no problem, but I have no idea yet how to pass or apply your fortran interface (below)to Fortran:

    Qt Code:
    1. // fortran interface - transpose it
    2. T& operator()(unsigned int x, unsigned int y)
    3. {
    4. return (array_)[y][x];
    5. }
    To copy to clipboard, switch view to plain text mode 
    same way as FMATRIX - examples in links above.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  12. #11
    Join Date
    Sep 2012
    Posts
    7
    Thanks
    1

    Default Re: How to get a pointer for 2D array of QVector?

    I was a little confused, and now understand what your codes mean.

    A basic question: If an array is created with FortranMatrix as follows
    Qt Code:
    1. void cppFN()
    2. {
    3. FortranMatrix < int, 3, 5 > intArray;
    4.  
    5. intArray(1,2) =1;
    6. ...
    7. }
    To copy to clipboard, switch view to plain text mode 
    a user does not need to delete the intArray. It will be cleared by OS when leaving the cppFN(). Is my understanding correct?

  13. #12
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    a user does not need to delete the intArray. It will be cleared by OS when leaving the cppFN(). Is my understanding correct?
    Yes, correct.

  14. #13
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    Quote Originally Posted by tfmp View Post
    I was a little confused, and now understand what your codes mean.

    A basic question: If an array is created with FortranMatrix as follows
    Qt Code:
    1. void cppFN()
    2. {
    3. FortranMatrix < int, 3, 5 > intArray;
    4.  
    5. intArray(1,2) =1;
    6. ...
    7. }
    To copy to clipboard, switch view to plain text mode 
    a user does not need to delete the intArray. It will be cleared by OS when leaving the cppFN(). Is my understanding correct?
    Quote Originally Posted by d_stranz View Post
    Yes, correct.
    but remember that in cpp code, you should be using 'at' to access the array elements, e.g
    Qt Code:
    1. void cppFN()
    2. {
    3. FortranMatrix < int, 3, 5 > intArray;
    4.  
    5. intArray.at(1,2) = 1; // not 'intArray(1,2)' <-- fortran-only syntax
    6. ...
    7. }
    To copy to clipboard, switch view to plain text mode 
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  15. #14
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    but remember that in cpp code, you should be using 'at' to access the array elements, e.g
    No, I think you woke up too early (or maybe are staying awake much too late).

    The code refers to your FortranMatrix template class, which has template methods for operator()( int, int ). His code is exactly correct for that class - the internal storage for that class is a C++ array allocated by operator new(), and the template class doe not define an "at()" method.

  16. #15
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    Quote Originally Posted by d_stranz View Post
    No, I think you woke up too early (or maybe are staying awake much too late).

    The code refers to your FortranMatrix template class, which has template methods for operator()( int, int ). His code is exactly correct for that class - the internal storage for that class is a C++ array allocated by operator new(), and the template class doe not define an "at()" method.
    I think you are confused.

    I know it refers to my FortranMatrix, which has operator()(...) ONLY for fortran - it is commented as such. Lets remind ourselves:
    Quote Originally Posted by amleto View Post
    I'd be interested in how well this works:
    Qt Code:
    1. template<class T, unsigned int M, unsigned int N>
    2. class FortranMatrix
    3. {
    4. public:
    5. FortranMatrix()
    6. :array_(new T[M][N])
    7. {}
    8.  
    9. // cpp interface
    10. T& at(unsigned int x, unsigned int y)
    11. {
    12. return (array_)[x][y];
    13. }
    14.  
    15. // fortran interface - transpose it
    16. T& operator()(unsigned int x, unsigned int y)
    17. {
    18. return (array_)[y][x];
    19. }
    20.  
    21. //pass the matrix to a fortran method accepting a T*
    22. operator T*()
    23. {
    24. return &(*array_)[0];
    25. }
    26.  
    27. private:
    28. T (*array_)[N];
    29. };
    To copy to clipboard, switch view to plain text mode 
    Quite clearly there IS a method 'at'. Funnily enough, I commented that this method to be used in cpp code, which is why I remarked that this method, and not operator()(...), should be used.

    Regards
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  17. The following user says thank you to amleto for this useful post:

    d_stranz (13th September 2012)

  18. #16
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to get a pointer for 2D array of QVector?

    Quite clearly there IS a method 'at'.
    And equally clear is the fact that I was the one up too early to be typing comments into the forum...

  19. #17
    Join Date
    Sep 2012
    Posts
    7
    Thanks
    1

    Default Re: How to get a pointer for 2D array of QVector?

    Thank you for all replies and comments, given above. The issue regrading data-sharing between Fortran and C++ is resolved.

Similar Threads

  1. 2D array in Qt: QVector or QList
    By timmu in forum Newbie
    Replies: 8
    Last Post: 26th April 2017, 17:08
  2. QVector array declear
    By zhxys in forum Newbie
    Replies: 8
    Last Post: 2nd February 2011, 09:17
  3. Replies: 1
    Last Post: 4th August 2010, 17:13
  4. use QVector as 2 dimensional Array
    By umulingu in forum Qt Programming
    Replies: 3
    Last Post: 1st January 2010, 12:31
  5. QVector crashes when array size is big
    By Sheng in forum Qt Programming
    Replies: 49
    Last Post: 27th February 2009, 22:13

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.