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

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).

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).

Create an N dimensional array, where N is determined at runtime (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

Creating a static array with a variable size?

I want to create an array which is not on the heap, but on the stack. The size of my array will be based on the number of lines in a file.
I found this SO post:
Why aren't variable-length arrays part of the C++ standard?
Is there still no way to create an array on the stack where the size is determined by something else, other than a const?
No, you can't create an array on the stack unless its size is known at compile time. Not just const, but compile-time constant.

why does c++11 std::array using template to initialize the max_size not constructor?

c++11 uses template to define the max_size of the array (eg. std::array<int, 5> a1;) but not constructor. (eg. std::array<int>(5) a1;)
Since template is going to generate code for the class, and if I have a lot of arrays just differs in sizes, there'll be a lot of code to be generated.
(1. It may cause increase in compile time.
2. It may cause the expension of the code part of the executable file.)
Because if it didn't, it wouldn't be able to be what it is.
std::array is an array. Not a dynamically-sized array. Not a runtime-sized array. It is an array, much like int arr[5].
C++ is a statically typed language, which means that C++ types must have a compile-time defined size. arr in the above example has a size; if you do sizeof(arr), you will get sizeof(int) * 5. sizeof(std::array<int, 5>) has a size as well, which is defined by the number of elements in it. Therefore, the size must be a compile-time defined quantity, since it factors into the compile-time defined size.
The differences between std::array and regular arrays are:
Arrays will decay into pointers implicitly. std::array does not; you need to explicitly call a function to do that.
Arrays are language arrays; std::array, to the language, is a struct which contains an array.
if I have a lot of arrays just differs in sizes, there'll be a lot of code to be generated.
Yes, you might. Then again... is this a serious concern? Have you really looked at a std::array implementation?
There's not much there. T operator[](int index) { return elems[index]; } I don't think getting a couple hundred instantiations of that function is going to be a problem. Same goes for begin, size, empty, etc. You're talking about code that will almost certainly be inlined.
std::array is meant as a thin wrapper over a fixed-sized array. For a dynamically-sized array, there is std::vector.
One benefit of std::array is that it allocates memory on the stack (unless you declare a global object) with minimal overhead.
If the array size was determined by a constructor parameter, allocation would have to be on the heap and in general the resulting object would be less efficient in terms of memory usage and performance.

what is the point of having static arrays

I don't have a background in C or C++, so static arrays puzzle me a little. What are they for? Why are they allocated on the stack?
I imagine there's a performance benefit. Stack allocation is faster and there's no need for garbage collection. But why does the length need to be known at compile time? Couldn't you create a fixed-size array at runtime and allocate it on the stack?
Dynamic arays or slices in D are represented by a struct that contains a pointer and a length property. Is the same true for static arrays? How are they represented?
If you pass them to a function, they are copied in their entirety (unless you use ref), what is the rationale behind that?
I realize that dynamic arrays and slices are much more imprtant in D than static arrays, that's why the documentation doesn't dwell on them very long, but I'd still like to have a bit more background. I guess the peculiarities of static arrays have to do with how stack allocation works.
static arrays hail from the C language where calls to (the slow) alloc were discouraged to the extreme because of memory leaks (when you forgot to free the allocated array), double freeing (as a result of...), dangling pointers (all dangers of manual memory management that can be avoided with GC)
this meant that constructs such as
int foo(char* inp){
char[80] buff;
strcpy(inp,buff);//don't do this this is a invite for a buffer overflow
//...
return 1;
}
were common instead of the alloc/free calls where you need to be sure everything you allocated was freed exactly once over the course of the program
technically you CAN dynamically allocate on the stack (using assembly if you want to) however this can cause some issues with the code as the length will only be known at runtime and lessen possible optimization that the compiler may apply (unrolling an iteration over it for example)
static arrays are mostly used for buffers because of the fast allocation possible on the stack
ubyte[1024] buff=void;//assigning void avoids the initializer for each element cause we are writing to it first thing anyway
ubyte[] b;
while((b=f.rawRead(buff[])).length>0){
//...
}
they can implicitly convert to a slice of the array (or explicitly with the slice operator []) so you can use them near interchangeably with normal dynamic arrays
Static arrays are value types in D2. Without static arrays, there would be no simple way to have 100 elements in a struct that are actually stored in the struct.
Static arrays carry their size as part of their type. This allows you to e.g. declare: alias ubyte[16] IPv6Address;
Unlike in C, D2 static arrays are value types through and through. This means that they are passed by value to functions, like structs. Static arrays generally behave like structs with N members as far as memory allocation and copying goes.
By the way, you can use alloca to allocate a variable amount of memory on the stack. C also has variable-length arrays.