CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
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
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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,765

    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
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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,513

    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 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.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured