Sune
Sune

Reputation: 239

Dynamically allocating memory in class constructor

I am trying to implement a class in C++ used to store the data of an optimization problem. The data is saved in a text file, and is of the form

So I do not know the dimensions of the problem before I read the file wherefore I need to allocate memory dynamically. What I have done so far is to publicly declare a pointer

int** C;

in the header file. And then in the constructor in the .cpp file I do

ifstream InFile( fname );
InFile >> n;
InFile >> m;
int** C = (int**) calloc(n, sizeof(int *));
for(int i=0; i<n; ++i){
  C[i] == (int*) calloc(m,sizeof(int));
  for(int j=0, j<m; ++j){
    InFile >> C[i][j];
  }
}

where fname is the data file given as an argument to the constructor. The problem occurs when I in a member function, call it ProcessData() try to access this pointer to the pointer to the integer array. It seems it changes address! When I do

cout << C;

In the constructor I get

0000000000359300

However, when I do the same in the member function I get

000000013F57710C100

Can anyone please tell me what I am doing wrong here? I am using Visual C++ in Visual Studio on a 64 bit Windows 7 machine.

Upvotes: 1

Views: 2137

Answers (3)

M.M
M.M

Reputation: 141574

The simplest way to do this is for your class to have a member vector. Vectors wrap the process of having a pointer and dynamically allocating memory to it, and they behave properly when you copy, move or destroy your object:

class MyClass
{
public:
    std::vector< std::vector<int> > C;

    MyClass(size_t rows, size_t cols):
        C( rows, std::vector<int>(cols, 0) )
    { }
};

It's probably a bad idea to do your user input inside the constructor; instead do the input (and check for success) and then construct the object:

size_t rows, cols;
if ( !(inFile >> rows >> cols) )
    throw std::runtime_error("input error");

MyClass obj(rows, cols);

Upvotes: 0

Puppy
Puppy

Reputation: 146920

Firstly, do not ever manage your own memory in C++. You can simply use std::vector<std::vector<int>> to manage it for you, which actually has a chance in hell of being correct.

Secondly, in the constructor, C is a local variable, so it cannot possibly have the same address as any other variable existing at the same time.

Upvotes: 0

The Dark
The Dark

Reputation: 8514

This line

int** C = (int**) calloc(n, sizeof(int *));

is declaring a new (local) variable and initializing it. To set the value of the member variable, just remove the declaration bit:

C = (int**) calloc(n, sizeof(int *));

Upvotes: 2

Related Questions