Nicolai
Nicolai

Reputation: 343

How to declare a pointer to a 2d float matrix?

Im trying to declare a pointer to a 2d float matrix in order to have a dynamical behaviour of my image data but Im having a compilation error C2057: expected constant expression. I thought a pointer had to be casted in that way but apparently not.. Please anyone could help me ? Thanks!!

    //Image size input

int imheight;
int imwidth;

cout << "Please, enter image height: \n>";
scanf ("%d",&imheight);
cout << "Please, enter image width: \n>";
scanf ("%d",&imheight);

const int imheight2 = imheight;
const int imwidth2 = imwidth;

float *zArray[imheight2][imwidth2];

Here is one of my other functions where I´m trying to hace access to zArray. Im not getting the data properly read:

void LoadRIS( char* inputFileName , float** zArray, int imageHeight , int  imageWidth){

    // Load input RIS file
FILE* lRis = fopen ( inputFileName, "rb" );

// Jump to data position
for (int i = 0; i < 88; i++){       
    uchar a = getc (lRis);   
}   

// Read z array
size_t counter = fread ( *zArray , 1 , imageHeight * imageWidth * sizeof(zArray) , lRis );

//Get max value of RIS
float RISmax = zArray [0][0];
float RISmin = zArray [0][0];
for (int i=0; i<imageHeight; i++) 
{
    for (int j=0; j<imageWidth; j++)
        {
            if (zArray[i][j] > RISmax)
            RISmax = zArray [i][j];
            if (zArray[i][j] < RISmin)
            RISmin = zArray [i][j];
        }
}
std::cout<<"The max value of the RIS file is: "<<RISmax<<"\n";
std::cout<<"The min value of the RIS file is: "<<RISmin<<"\n";
Beep(0,5000);


// Close input file
fclose (lRis);

}

Upvotes: 0

Views: 5899

Answers (7)

t_smith
t_smith

Reputation: 89

float *pMatrix = new float[imheight2*imwidth2];

then access elements like this

float f = pMatrix[x + imwidth2 * y];

Upvotes: -1

Pixelchemist
Pixelchemist

Reputation: 24956

You cannot use Arrays with dynamic sizes (your width and height variables are not compile time constant).

You can either use malloc() or new Operator to allocate Memory in a dynamic fashion.

Upvotes: 0

hongtao
hongtao

Reputation: 406

Try this (dynamical allocation)

//Image size input

int imheight;
int imwidth;

cout << "Please, enter image height: \n>";
scanf ("%d",&imheight);
cout << "Please, enter image width: \n>";
scanf ("%d",&imwidth);

float** zArray = new float*[imheight];
for(int i=0;i<imheight;i++){
    zArray[i] = new float[imwidth];
}

Of course you need to free the allocation by:

for(int i=0;i<imheight;i++){
    delete[] zArray[i];
}
delete[] zArray;

Hope this helps :)

P.S. As @FrankH says, this calls too many news and deletes, wasting a lot of time. Better idea should be to alloc imwidth*imheight space together.

Upvotes: 1

FrankH.
FrankH.

Reputation: 18227

If you have to do this, then code it at least as:

float **zArray = new float*[imheight];
float *tmp = new float[imheight*imwidth];

for(int i=0; i<imheight; i++, tmp += imwidth)
    zArray[i] = tmp;

...
delete[] *zArray;
delete[] zArray;

This at least avoids doing more than two new / delete[] calls. And it preserves the functionality of your fread(*zArray, ...) which breaks if the memory isn't contiguous (and it won't generally be if you initialize this via many new calls).

A proper wrapper class would do just a single new / malloc, like:

template <class T> class Array2D {
private:
    size_t m_x;
    T* val;
public:
    Array2D(size_t x, size_t y) :
        m_x(x)),
        val(new T[x*y]) {}
    ~Array2D() { delete[] val; }
    T* operator[](size_t y) { return val + y*m_x; }
}

You still cannot assign an instance of this to a float**. And it still allocates on the heap, where ordinary constant-dimension arrays can be on the stack. The only advantage of the additional allocation for the float** is that you're not bound to use a multiplication operation - but a separate memory access instead; that type of behaviour could be templated / traited into the wrapper class.

Generically, I'm more on the side of multidimensional arrays are evil (see also https://stackoverflow.com/a/14276070/512360, or C++ FAQ, 16.16) but tastes vary ...

Upvotes: 1

fatihk
fatihk

Reputation: 7919

instead of float *zArray[imheight2][imwidth2]; it should be:

float **zArray = new float*[imheight2];

for(int i=0; i<imheight2; i++)
{
    zArray[i] = new float[imwidth2];
}

Upvotes: 2

user123
user123

Reputation: 9071

The problem is that you're declaring 2 const int variables but you're not assigning them const values. imheight and imwidth are not constant.

If you're fine with STL:

std::vector<std::valarray<float> > floatMatrix;

edit: Just for your information, the space I placed between the > in the above line of code has nothing to do with my coding style. Your compiler might assume that >> is the right shift operator instead of 2 template argument list terminators. Angew's comment below sums it up.

Upvotes: 2

ForEveR
ForEveR

Reputation: 55897

const int imheight2 = imheight;
const int imwidth2 = imwidth;

It doesn't make constant expressions. You cannot create array with such bounds. You should use dynamic-allocation, or vector.

Upvotes: 2

Related Questions