CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
+ Reply to Thread
Results 1 to 6 of 6
  1. #1
    Join Date
    Jun 2010
    Posts
    2

    Strage problem with arrays

    I'm writing a general purpose templated library for vector and matrix math. I want to be able to initialise a matrix with a 2D array. A matrix consists of an array of column vectors. A vector can take a pointer to a 1D array of initial values. I've tested that this works. But the similar constructor for the matrix causes a sigsegv. As far as I can see, all the array math is fine. From the stack trace, the value for initArray in Vec<4,float>::Vec is bogus. It should be pointing to the first element of one of the inner arrays of the 2D array passed into Mat<4,4,float>::Mat in main.

    Here's a copy of the call stack at the time of the error:

    #0 00417483 Math::Vec<4u, float>::Vec(this=0x28fd30, initArray=0x3f800000) (E:/Documents/Prog/mathlib/vec.h:145)
    #1 00417292 Math::Mat<4u, 4u, float>::Mat(this=0x28fe90, initArray=0x28fed0) (E:/Documents/Prog/mathlib/mat.h:80)
    #2 00401505 main() (E:/Documents/Prog/mathlib/test_main.cpp:16)
    And here is the relevent code from those functions:

    main
    Code:
    typedef Math::Mat<4, 4> Mat4;
    
    float mat_init[4][4] = {    {1, 0, 0, 0},
                                {0, 1, 0, 0},
                                {0, 0, 1, 0},
                                {0, 0, 0, 1}    };
    
    Mat4 m1((const float**)mat_init);     // Error here
    Mat4 m2((const float**)mat_init);
    Matrix constructor
    Code:
    template <unsigned int X, unsigned int Y, typename T>
    Mat<X, Y, T>::Mat(const T** initArray) {
        for (unsigned int i=0; i<X; ++i)
            cols[i] = Vec<Y, T>(initArray[i]);
    }
    Vector contructor
    Code:
    template <unsigned int N, typename T>
    Vec<N, T>::Vec(const T* initArray) {
        for (unsigned int i=0; i<N; ++i)
            els[i] = initArray[i];
    }
    And the interfaces for vectors and matrices
    Code:
    template <unsigned int N, typename T = float>
    class Vec {
        public:
            Vec();                          // Init elements to default value of type T
            Vec(const T* initArray);        // Init from array of N elements of type T
            Vec(const T& initVal);          // Init all elements to initVal
            Vec(const Vec& copy);
            ~Vec();
    
            Vec& operator= (const Vec& rhs);
    
            T& operator[] (unsigned int i);
            const T& operator[] (unsigned int i) const;
    
            // Cast to any other type of vector (any dimensions, any element type)
            template <unsigned int n, typename t>
            operator Vec<n, t> () const;
    
        private:
            T els[N];
    };
    Code:
    template <unsigned int X, unsigned int Y, typename T = float>
    class Mat {
        public:
            Mat();
            Mat(const T** initArray);           // Init by array T [X][Y]
            Mat(const Vec<Y, T>* initArray);    // Init by array of column vectors
            Mat(const Mat& copy);
            ~Mat();
    
            Mat& operator= (const Mat& rhs);
    
            Vec<Y, T>& operator[] (unsigned int);
            const Vec<Y, T>& operator[] (unsigned int) const;
    
        private:
            // Store elements as X columns of Y elements of T
            Vec<Y, T> cols[X];
    };
    Thanks.

  2. #2
    Lindley is offline Elite Member Power Poster Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+)
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,861

    Re: Strage problem with arrays

    Quote Originally Posted by CodeHippie View Post
    Mat4 m1((const float**)mat_init); // Error here
    Mat4 m2((const float**)mat_init);
    You've encountered an unintuitive but perfectly reasonable issue: a "2D array of T" is not the same as a T**. The fact that you needed an explicit cast to make the compile work should have been your first clue on this matter.

    Basically, with a 2D array, the memory layout doesn't include any room for pointers. It doesn't need to; the dimensions are known at compile time, so the compiler can convert multi-dimensional accesses into 1D accesses at compile time.

    With a T**, though, you've explicitly got to have an array of pointers. It's a different underlying assumption.

    I would also point out that there are several good vector/matrix math libraries out there already: Boost.uBLAS, Eigen, MTL, etc.

  3. #3
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,027

    Re: Strage problem with arrays

    An array of arrays can be converted to a pointer to an array, but a pointer to an array is not a pointer to a pointer. You should cater for this by having a pointer to an array instead of a pointer to a pointer as the parameter.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  4. #4
    Join Date
    Jun 2010
    Posts
    2

    Re: Strage problem with arrays

    Right, of course! Thanks a lot man.

  5. #5
    Lindley is offline Elite Member Power Poster Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+) Lindley has much to be proud of (1500+)
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,861

    Re: Strage problem with arrays

    If you really want to get confused, try and figure out why the compiler will refuse to implicitly convert a T** to a const T**.

  6. #6
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,273

    Re: Strage problem with arrays

    Quote Originally Posted by Lindley View Post
    If you really want to get confused, try and figure out why the compiler will refuse to implicitly convert a T** to a const T**.
    Or explicitly as a matter of fact.
    Is your question related to IO?
    Read this C++ FAQ LITE article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

+ Reply to Thread

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



HTML5 Development Center

Click Here to Expand Forum to Full Width