Bogdan Maier
Bogdan Maier

Reputation: 683

C++ struct constructor error

i`m working on my assignment for univ, and since some parts are not really good explained i got some problems there is my structure and my constructor for it, it has to be dynamical but i get the fallowing error. Some help is really appreciated thank you. .h:

const int days=31;
const int exp=6;

struct Array{
int days;
int exp;
int **M;
};

.cpp:

void constr(Array &loc){
//Construct of 31*6 Matrix, were 31 nr. of days and 6 specific types:
//0-HouseKeeping, 1-Food, 2-Transport, 3-Clothing, 4-TelNet, 5-others
loc.days = days;
loc.exp = exp;
loc.M=malloc(loc.days*sizeof(int*));
for(int i=0; i<loc.days;i++ ){
    loc.M[i] = malloc(loc.exp*sizeof(int));
    for (int j = 0; j< loc.exp; j++){
        loc.M[i][j] = 0;
    }
}
}

error:

..\src\structs.cpp: In function 'void constr(Array&)':
..\src\structs.cpp:7:36: error: invalid conversion from 'void*' to 'int**'    [-fpermissive]
..\src\structs.cpp:9:40: error: invalid conversion from 'void*' to 'int*' [-fpermissive]

Upvotes: 0

Views: 859

Answers (4)

Adrien
Adrien

Reputation: 146

Please, stop using std::vector > or, worse T tab[][] for representing a 2D array. You should use a 1D array to store data, a an index array to store row pointers. That way, your data remains contiguous, and you still can have a nice syntax.

  template<typename T>


class Array2D



{
    std::vector<T>  m_data;
    std::vector<T*> m_ptr;
    size_t m_iWidth;
    size_t m_iHeight;

    void Link(void)
    {
      for (unsigned int j = 0; j < m_iHeight; ++j)
        m_ptr[j] = &m_data[j * m_iWidth];
    }


  public:
    Array2D(void)
    {
    };
    Array2D(const size_t i_width, const size_t i_height) :
      m_iWidth(i_width),
      m_iHeight(i_height),
      m_data(i_width * i_height),
      m_ptr(i_height)
    {
      Link();
    }


    void Resize(const size_t niou_width, const size_t niou_height)
    {
      if (m_iWidth == niou_width && m_iHeight == niou_height)
        return;

      m_iWidth  = niou_width;
      m_iHeight = niou_height;

      m_data.resize(niou_height * niou_width);
      m_ptr.resize(niou_height);
      Link();
    }


    typename std::vector<T>::iterator begin(void)
    {
      return m_data.begin();
    }


    typename std::vector<T>::iterator end(void)
    {
      return m_data.end();
    }


    void assign(T value)
    {
      m_data.assign(m_iWidth * m_iHeight, value);
    }


    Array2D(const Array2D& a) :
      m_iWidth(a.m_iWidth),
      m_iHeight(a.m_iHeight),
      m_data(a.m_data)
    {
      m_ptr.resize(m_iHeight);
      Link();
    }


    Array2D& operator=(const Array2D a)
    {
      swap(*this, a);
      return *this;
    }

    template <typename U>
    friend void swap(Array2D<U>& first, Array2D<U>& second)
    {
      using std::swap;
      swap(first.m_iHeight, second.m_iHeight);
      swap(first.m_iWidth, second.m_iWidth);
      swap(first.m_data, second.m_data);
      swap(first.m_ptr, second.m_ptr);
    }

    ~Array2D()
    {
    };

    T* operator[](const size_t ligne)
    {
      return m_ptr[ligne];
    };
    const T* operator[](const size_t ligne) const
    {
      return m_ptr[ligne];
    };

    T& operator()(const size_t col, const size_t lig)
    {
      return m_ptr[lig][col];
    };
    const T& operator()(const size_t col, const size_t lig) const
    {
      return m_ptr[lig][col];
    };

Upvotes: 0

Stephan
Stephan

Reputation: 4247

Since you asked for C++ constructors in your comment... See the code below. I also replaced your two-dimensional C-style array with a C++ vector. I added code comments to the relevant lines:

Array.h:

#pragma once

#include <vector>

struct Array
{
    // this is a c++ constructor declaration
    Array(int daysParam, int expParam);

    int days;
    int exp;

    // use a vector of vectors instead allocating with new or malloc
    // it is easier to initialize and the compiler will clean it up for you
    std::vector<std::vector<int> > M;
};

Array.cpp:

#include "Array.h"

// Array constructor definition with initializer list
// all data members are initialized here by invoking their constructor
Array::Array(int daysParam, int expParam)
    : days(daysParam), 
      exp(expParam), 
      M(daysParam, std::vector<int>(expParam, 0))
{
}

Example for usage of Array (Program.cpp):

#include "Array.h"

int main()
{
    // create a new Array, using the c++ constructor
    Array myArray(31, 6);

    // access elements in the 2-dimensional array
    int singleValue = myArray.M[15][3];

    return 0;
}

I strongly advise you to read a book about C++

Upvotes: 3

Luchian Grigore
Luchian Grigore

Reputation: 258678

Since this is C++:

loc.M = new int*[loc.days];
for(int i=0; i<loc.days;i++ ){
   loc.M[i] = new int[loc.exp];
   for (int j = 0; j< loc.exp; j++){
       loc.M[i][j] = 0;
   }
}

Upvotes: 2

k06a
k06a

Reputation: 18825

loc.M = (int**)malloc(loc.days*sizeof(int*));
loc.M[i] = (int*)malloc(loc.exp*sizeof(int));

Upvotes: 1

Related Questions