Create an N dimensional array, where N is determined at runtime (C++) - c++

I'm encoding N-Dim image cubes into a different image format. I don't know the dimensions of the image until runtime and the library I'm using to read from the original image needs an N-dim array destination buffer as a parameter.
How can I declare such an array in C++? Thanks :)

The short answer is that you cannot declare such an array in C++. The dimensions of an array are part of the type (with a miscellaneous exception that sometimes the value of one of the dimensions can be unknown, for an extern array declaration). The number of dimensions is always part of the type, and the type must be known at compile time.
What you might be able to do instead is to use a "flat" array of appropriate size. For example, if you need a 3x3...x3 array then you can compute 3^n at runtime, dynamically allocate that many int (probably using a vector<int> for convenience), and you have memory with the same layout as an int[3][3]...[3]. You can refer to this memory via a void*.
I'm not certain that it's strictly legal in C++ to alias a flat array as a multi-dimensional array. But firstly the function you're calling might not actually alias it that way anyway given that it also doesn't know the dimension at compile-time. Secondly it will work in practice (if it doesn't, the function you're calling is either broken or else has some cunning way to deal with this that you should find out about and copy).

You can't use array in this case. Array is only for those data whose size and dimension are known at compile time. Try use an array of std::vector instead

Related

how can deal with float *array

I have array declared in something like this
first way
int size=256*10;
float *array=(float*)malloc(size * sizeof(float));
for(int i=0;i<2398;i++)
data[i]=data[i]*900;
When I used this why in declaration my code run with out errors but
when I use the array as constant values like this :
2nd way
float array[]={120.0, 160.0, 255.0, 216.0, 255.0, 224.0, 0.0, 16.0,
74.0, 70.0, 73.0, 70.0, 0.0, 1.0, 1.0};
I didn't get what was required from the code even if I took the array output in the first way and defined it as in 2nd way?!!
I thought defining an array in the 2nd way is correct and equivalent to the first definition?!
What is the correct way to declare an array that equivalent to the first way?
Both ways create valid arrays, and you can use them pretty much exchangably if you pay attention to object life time. The differences are:
malloc dynamically allocates memory which exists until the program explicitly calls free() on the address returned by malloc. One of the typical use cases is to allocate and initialize some storage in a function and let the function return the address. That's fine: The life time of objects in dynamically allocated memory (new, malloc) is independent of scope (e.g., a function).
By contrast, an array defined the second way exists until the variable goes out of scope. If it is a global variable it will exist until the program ends. If it is defined in a function it will only exist until the program returns from the function, or ends. That may be your problem here. Returning the address of a function-local object and using it outside that function is a not uncommon error. Newer compilers with sufficiently high warning levels should warn when they see such a mistake.
The second array is an object with the number of elements indicated by the initializers, exactly. You can call sizeof(array) and get a large number, for example 60. The first "array", by contrast, is not an array at all: It is a pointer to the first element of an array. Calling sizeof() on that pointer returns the size of that pointer, typically 4 or 8, no matter how much memory is allocated at the location the pointer points to. There is no built-in way to keep track of the size of the allocated memory — the programmer must store it somewhere. Typically, larger programs have a constant or a define somewhere in a header shared by "translation units" (source files) so that parts of the program that use the allocated memory don't overshoot its limits, and the part allocating it knows how much is needed.
Standard C++ doesn't have variable length arrays: Array sizes must be known at compile time. That's obviously not always possible. For example, most image formats contain the image size in the first few bytes of the file. A program reading such an image would read a few bytes into an information structure and then dynamically allocate the needed memory for the actual pixels. If you want to use compile-time sized arrays you can, of course, simply define one that's big enough for large pictures and only use part of it for smaller ones. But you'll end up with array sizes that normally waste space because they are much too large for the average picture — but will probably still not fit the largest picture they may encounter! It is much better to use a data structure whose size can be determined or changed at run time, like a std::vector, or arrays created with new() or, if you must, malloc().
Remarks:
You don't use the entire allocated memory which is a bit strange: You allocate 2560 floats but assign values only to 2398.
The assignment data[i]=data[i]*900; reads from the uninitialized element data[i] before assigning to it. Reading uninitialized memory is verboten and kaput ("undefined behavior"), and the program is faulty. In practice you'll probably simply have funny float values, but still. Don't do it.
If you have an array you want to initialize with a few dozen values known at compile time I'd strongly prefer a true array. If it needs to live longer than the function you can make it static and let the function return a pointer to it.
Only if you need a lot of memory (2500 floats qualifies) or must create an array whose size is unknown at compile time, or must create an unknown number of arrays, consider creating them dynamically.
As others have remarked in comments, real-world code would use a vector or a smart pointer and/or std::array. Explicit dynamic allocation has pretty much become a domain of beginner homework (I'm not condescending: It has its place there) or projects stuck with old compilers (don't ask).

C++ Declaring a 2d array with a size function

I'm trying to declare a 2d array by using the size() method for STL map:
const int size = edge_map.size();//get row and column size
int a[size][size];//nxn matrix
I keep getting a compiler error that the size must be a constant value even though I am declaring it as a constant. Is there any work around for this without having to use a dynamic 2d array?
Static memory allocation for arrays can accept variables as long as the value of the variable can be determined at compile-time. The reason for this requirement is because the compiler must know how much memory to allocate for the array on the stack. If edge_map is what it sounds like (some kind of container which can change sizes throughout its existence), you are not going to be able to do it this way.
If this is not the case, though, and edge_map.size() has a return value which can be determined at compile-time, marking that function as constexpr should allow this code to work.
const means to not change its original (initial) value.
But size must be known at compile time, as the compiler/linker allocates memory for non-local variables (declared out of any function).

Point to 3dimensional array in c++

I have searched on google but only found answers for single-dimension arrays.
I have a 3 dimension array storing data to be later processed by a function.
My array looks like this : levelcode[400][20][100]. It stores all the info that the decode level function needs. I get an stack overflow error immediately.
But how can i point to the entire array to get the values of it ( or how do i pass down the entire array? ) ?
I know i can technically call the function for each existing parameter but i think it would be faster and it would look better if the entire array was passed down or being used using a pointer of some sort.
How can i accomplish this?
I suggest you use a std::vector. It is basically a self managed grow-able array. It stores the data dynamically(heap) so you will be using the full system memory instead of the small bit of memory the program is given for automatic objects(stack). With your levelcode[400][20][100] you have 800,000 elements. if the array is of type int then you would more than likely need 3.2MB of space for the array. typically this is larger than than the space provided to the program and will cause a stack overflow
I would suggest you use single dimension vector and then you can use math to fake the 3 dimensions. This will make the data more cache friendly as multi-dimensional vectors do not have to have each dimension located right next to each other like a multi-dimensional array does.
So instead of having a
std::vector<std::vector<std::vector<some_type>>> name{DIM1, vector<vector<some_type>>{DIM2, vector<some_type>{DIM3}}};
and using it like
name[x][y][z]
We could have a
std::vector<some_type> name{DIM1 * DIM2 * DIM3};
and then you can access the elements with
name[x*DIM2*DIM3 + y*DIM3 + z]

2D arrays and dynamic arrays

I have a class which just contains a 1D array of set size (17): However this array needs to be for every monitor that a user has and I am unsure whether to simply set say and array of size 10 limiting the user, or whether to try a more dynamic approach.
Excerpt from ScreenArray.h:
private:
unsigned long pixelArray[17];
I would like advise to which method(s) will work best for my problem and how would I go about constructing / allocating and accessing it?
EDIT: The array (Or the 2D part of the array) preferably dynamic to the size of the monitors currently connected. This contains the 1D array of set size 17.
As UnholySheep stated out, vector is a great tool to use in this situation:
Variable size;
Out of range protection;
Automatic memory management;
...
The only drawback I see may be a loss in performance, but because your vector is so small, you won't even be able to measure it, so this doesn't count.
You can use it like so:
// You'll need this one
#include <vector>
// Create you vector
// Replace TYPE with the type of it's members.
std::vector< TYPE > pixelArray;
// Add members to it
pixelArray.push_back( MEMBER );
// Access it as usual
pixelArray[n];

Dynamic Array in C++ vs ArrayList in Java

I am new to C++. I am working on a problem from class. We must use Dynamic Arrays to read words from a file.
Here are my simple questions.
Does Dynamic Array imply the use of a pointer? Meaning we point at our new array made.
In Java, ArrayList can be created and size changes dynamically. But to me in C++, does using a dynamic array mean to set the size of the array to a large number and then dynamically allocate that array?
Is there no way to chop off the excess indexes from the dynamic array? So then delete the array at the end is the only choice I have in C++?
Thanks, pointers and dynamic arrays can only be used. Thank you.
Java ArrayList is only comparable to C++ Vector. A normal dynamic array does not change it's size at runtime so if you declare a dynamic int array in c++:
int *arr = new int[10];
The size of that array will remain at 10.
However if you use vector:
std::vector<int> arr(10);
Then when this vector is filled past 10 elements, the vector object automatically allocates more memory for itself.
So to answer your question, dynamic array implies making use of a pointer to keep track of the memory location where the heap-allocated array has been placed. But if you use vector, this is handled for you internally
I suppose dynamic array could refer either. Look at what you have to do and decide. Does it make scene to use an array where the size is fixed? I'm guessing that a vector would be the best here since you probably don't know ahead of time how large the file is.
std::vector<string> words;
Also just for your information the vector class simply stores a pointer to a dynamically allocated array. It creates a new one whenever you need more room, copies over the the data from the old array, and the deletes it. This all happens behind the scenes.
The C++ equivalent of a Java ArrayList is std::vector. You use the capitalized term "Dynamic Array" as if it has a specific meaning rather than the generic adjective "dynamic" applied to the concept "array". A "dynamic array" in C++ spec lingo is a local variable that has a fixed size, set when it is initialized/created, but that may get a different size each time the scope is entered (and the array recreated). Since it's local to a scope, its not too useful for storing stuff read from a file other than temporarily. C++ also has heap-allocated arrays which have their size set when created (as with a dynamic array), but which persist until explicitly deleted, which might be more useful. These are "dynamic" in the general adjective sense, but are not "dynamic arrays" in the spec sense.