Irritating MSVC compiler behavior with arrays

Carlos Milovic

Well-known member
Hi guys

There are some times when I need to make an array with a constant length, but that depends on the image dimensions, or other parameter. For example, this:

int n = image.Width();
float vector[n];

While this compiles (and works) well under Linux, MS refuses to compile it. Most times I just avoid using standard arrays, and just create a Array<float> object, but I have I case where for compatibility issues with other libraries, I'm forced to use that kind of arrays. Do you know of other workaround, rather than using a large number?
 
Hi Carlos,

arrays in C++ are basically pointers to memory. So you can malloc the appropriate amount of space, point to it and then use array notation to access it:

float *ar;
ar = (float*)malloc(n * sizeof(float));

ar[0] = 0.1;
ar[n-1] = 2.3;

free(ar);
ar = 0;

etc.

I'm sure C++ purists would insist that you use array templates or classes instead but this (or something similar) should work.
 
Hello Carlos,

you can also try little bit less-C and more-C++ way:

int n = image.Width();
float* vector = new float[n];

...

delete []vector;

There are two differences:
1) It's IMHO much more readable.
2) In case array type is not basic type (like int, float, double) but a class, using delete [] operator ensures calling destructor for each class instance in the array.

regards, Zbynek
 
I fully agree with Zbynek in the advantages of the new and delete C++ operators over the C malloc/calloc/free allocation scheme. That said, knowing and understanding standard C allocation is absolutely necessary IMO to gain the required perspective, even if we are using C++.

If you are using PCL, my recommendation is to use the GenericVector<T> template class (see pcl/Vector.h). GenericVector<> is a lightweight yet powerful implementation of a list of items of constant length. It uses shared memory (reference counted, so you can return it as a value from a function for example) and is thread-safe (you can use a single vector from several parallel running threads).

If you want to use fixed-length sequences of float, then you should use the FVector template instantiation. For example:

FVector a( 10 ); // a vector of 10 float components
FVector b( 10 ); // another one
...
a[3] = .123F; // implements array subscript operators
...
b *= 4; // implements scalar-assignment operators
...
FVector c = a + b; // implements vector algebra
...
float d = a * b; // dot (scalar) product
...
FVector c = FVector( 1, 2, 3 ) ^ FVector( 4, 5, 6 ); // cross (vector) product

... and so on. If you have to interface with C libraries, it is also very easy. Just use the FVector::Begin() member function, or ?more elegantly? FVector::eek:perator *(). Both members return a pointer to the internal array of floats stored in the FVector object.
 
I'm passing the arrays to C++ functions, defined by CMinPack. So, I have not much space here to try other things :p

BTW, Juan, I'm sending to you the whole "Calcium" module at the current state (v1.1). I think it has some cool stuff inside that may inspire you to do other new processes for PI ;).
 
Back
Top