I want to malloc an array in my code, and its size should be defined at runtime.
I tried like this:
#include <iostream>
#include <array>
int main(){
int M=4,N=3,P=5;
M=N+P;
std::array<std::array<double,M>,N> arr;
}
But MSVC told me:
a variable with non-static storage duration cannot be used as a non-type argument
I don't find the answer to this in stackoverflow.(The existing question seem not to solve my problem...)
How to dynamically allocate a 2D std::array in C++?
I know I could use std::vector to solve this. But the vector memory size needs to be organized by myself and this would be used many times in my project. And I want to use C++ type code rather than C type...Maybe there is a method to turn a 2D array in C type to std::array, but I can't find it by Google...
So I ask this question...
I mean the M and N should be got dynamically(not changed,but I can only know it in runtime...),like:
#include <iostream>
int main(){
int a=3;
int b=4;
int rowCount=a+b;
int colCout=b-a;
int** a = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
{
a[i] = new int[colCount];
}
}
I know where is my mistake. I fell into a logical question... If I don't use push_back,the vector works well. If I use it, the array doesn't work, too.
I think the capcity of vector is bigger than its size, I want to avoid this. But another question: How to limit the capacity of std::vector to the number of element show I should use my allocator or std::vector::shrink_to_fit() to avoid it...(There is no guarantee in C++17 if you use reserve(n))
The dynamically allocated array container in C++ is std::vector. std::array is for specifically compile-time fixed-length arrays.
https://cppreference.com is your friend!
But the vector memory size needs to be organized by myself
Not quite sure what you mean with that, but you specify the size of your std::vector using the constructor.
std::vector<std::vector<int>> arr(N);
If you need some special allocator (not just new/malloc), then you can also specify a custom allocator.
Your whole program that you propose is not good C++. A C++ solution would look like:
#include <vector>
int main() {
int a = 3;
int b = 4;
unsigned int rowCount = a + b;
unsigned int colCount = b - a;
std::vector<std::vector<int>> matrix(rowCount);
for (auto& row : matrix) {
row.resize(colCount);
}
}
std::array, like an actual array in C++, requires a constant size. It's what gives it any advantage at all over std::vector.
For a technical explanation as to how that requirement is implemented, remember that template parameters are required to be compile-time constants (since it changes how the code is generated, again at compile-time).
Anyway, you want to use std::vector here. If you know the size you want, give it as a constructor parameter.
In a program I am writing, I need to use often integer arrays of length 3 and I thought I should define a custom type. The integers they will hold are between 0 and 2, so int8 is more than enough. My goal is to avoid having to check explicitly for length.
I could do something of the form:
class MyArr {
int8_t a;
int8_t b;
int8_t c;
}
but I would also like to be able to access the elements using [], e.g. to be able to write x[0] instead of x.a. What is the optimal way to do that?
Also I guess I have to check that the values are legal, i.e. between 0 and 2 in the constructor. Is there any better way?
I think the best way is to use std::array and if you want bounds checking you can use the at() function instead of operator[].
https://en.cppreference.com/w/cpp/container/array/at
Example:
#include <array>
std::array<int8_t, 3> data = { 1, 2, 4 };
// Set element 1
data.at(1) = 88;
Use an array. Use std::array if you want value semantics. If you use this type very often and want a name more meaningful than a generic "array", you can use a type alias:
// Example with a 3D vector
using vec3D = std::array<std::int8_t, 3>;
vec3D v1, v2; // 3D vectors
I'm trying to pass a variable of type vector<vector<double> > to a function F(double ** mat, int m, int n). The F function comes from another lib so I have no option of changing it. Can someone give me some hints on this? Thanks.
vector<vector<double>> and double** are quite different types. But it is possible to feed this function with the help of another vector that stores some double pointers:
#include <vector>
void your_function(double** mat, int m, int n) {}
int main() {
std::vector<std::vector<double>> thing = ...;
std::vector<double*> ptrs;
for (auto& vec : thing) {
// ^ very important to avoid `vec` being
// a temporary copy of a `thing` element.
ptrs.push_back(vec.data());
}
your_function(ptrs.data(), thing.size(), thing[0].size());
}
One of the reasons this works is because std::vector guarantees that all the elements are stored consecutivly in memory.
If possible, consider changing the signature of your function. Usually, matrices are layed out linearly in memory. This means, accessing a matrix element can be done with some base pointer p of type double* for the top left coefficient and some computed linear index based on row and columns like p[row*row_step+col*col_step] where row_step and col_step are layout-dependent offsets. The standard library doesn't really offer any help with these sorts of data structures. But you could try using Boost's multi_array or GSL's multi_span to help with this.
The way I see it, you need to convert your vector<vector<double> > to the correct data type, copying all the values into a nested array in the process
A vector is organised in a completely different way than an array, so even if you could force the data types to match, it still wouldn't work.
Unfortunately, my C++ experience lies a couple of years back, so I can't give you a concrete example here.
Vector< Vector< double> > is not nearly the same as a double pointer to m. From the looks of it, m is assumed to be a 2-dimensional array while the vector is could be stored jagged and is not necessarily adjacent in memory. If you want to pass it in, you need to copy the vector values into a temp 2dim double array as pass that value in instead.
I apologize for the total noob question, but I just cannot find an answer. I googled, searched here, searched C++ array documentation, and some C++ array tutorials.
The question is simple. Why does
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
short pixelarray[3][3] = {{1,1,1},{0,0,0},{-1,-1,-1}};
... //do stuff. Imagine a loop here, and BIG array - I'm just simplifying it for StackOverflow
pixelarray = {{1,0,-1},{1,0,-1},{1,0,-1}};
return 0;
}
result in an error?
1>arraytest.cpp(11): error C2059: syntax error : '{'
How do I put a static array inside my array? I realize I could set each item individually, but there has to be a better way.
Built-in arrays in C++ have their problems, and not being assignable does make them rather inflexible. I'd stick with std::array, a C++11 container that emulates a better style of array, which allows a somewhat similar syntax to what you're looking for:
std::array<int, 3> arr{{1, 2, 3}};
std::array<int, 3>{{4, 5, 6}}.swap(arr);
//now arr is {4, 5, 6}
Here's a full sample. The trick is to use the initializer list on a newly-constructed array and then swap that with yours. I believe that the next C++ update is going to remove the need for the double braces as well, which makes it an even closer match to familiar syntax.
Initializer lists can be used just for initialization :)
Like when you declare your variable:
short pixelarray[3][3] = {{1,1,1},{0,0,0},{-1,-1,-1}}; // this is ok
You have to remove this:
pixelarray = {{1,0,-1},{1,0,-1},{1,0,-1}};
And assign new values manually (i.e. pixelarray[x][y] = or with a memcpy(pixelarray, <some other array>, sizeof(pixelarray)))
If you don't want to assign each individual element manually, you can do this:
short pixelarray2[3][3] = {{1,0,-1},{1,0,-1},{1,0,-1}};
memcpy(pixelarray, pixelarray2, sizeof(pixelarray));
As #Nick points out: initializer lists are not for assignment.
Arrays are not assignable, so the short answer is that you can't do exactly what you're asking for. The most direct way to do something similar enough for most purposes is probably a 2D array class that acts as a wrapper around a std::vector, on the order of the one I posted in a previous answer.
If you insist on staying with C-style arrays, one possibility would be to use a pointer:
int main() {
typedef short array[3];
array pixelarray0[3] = {{1,1,1},{0,0,0},{-1,-1,-1}};
array pixelarray1[3] = {{1,0,-1},{1,0,-1},{1,0,-1}};
array *pixelarray = pixelarray0;
// when needed:
pixelarray = pixelarray1;
}
Taking this question from a straight C context, you can have different constant arrays and just copy them with memcpy:
typedef short TArray[3][3];
const TArray a1 = {{1,1,1},{0,0,0},{-1,-1,-1}};
const TArray a2 = {{1,0,-1},{1,0,-1},{1,0,-1}};
// ...
TArray a;
memcpy( a, a2, sizeof(TArray));
Or you could exploit C99 struct copying, but I'd consider this a dangerous hack because the structure might be padded to be larger than the array, or have a different alignment.
typedef struct {
TArray arr;
} TDummyArray;
// ...
TArray a;
*(TDummyArray*)a = *(TDummyArray*)a2;
Once you have declared your array there is no way to use the assignment operator to reassign the entire content of the array.
So to change the contents or your array after this:
short pixelarray[3][3] = {{1,1,1},{0,0,0},{-1,-1,-1}};
You need to either loop through the array and manually change each value, or you something like std::memcpy to copy your new values over.
But you should really not be using an array in the first place, use some fromthing the std collections library instead like std::array or std::vector. Only use arrays if you have a really really good reason why you can't use a collection.
For some reason this is giving me more trouble than i thought...
int *myArray[3];
myArray = new int[mySize];
does not work...
I've used a typedef before in a similar manner and it worked perfectly, but this time i dont want to create the typedef
One might be tempted to do this:
::std::vector<int[3]> myArray;
Because vector is so nice for dynamically sized arrays. Unfortunately, while that declaration works, the resulting vector is unusable.
This will be just as efficient, if you have ::std::array (a C++11 feature) and it will actually work:
::std::vector< ::std::array<int, 3> > myArray;
If you can do this, I would highly recommend it. vector is much nicer and safer to deal with than an array you have to allocate yourself with new.
Otherwise, try this:
typedef int inner_array_t[3];
inner_array_t *myArray = new inner_array_t[mySize];
And since you don't want to use a typedef for some odd reason, you can unwrap it like so:
int (*myArray)[3] = new int[mySize][3];
int (*myArray)[3] = new int[mySize][3];
?
int *myArray[3];
This means "myArray shall be an array of three pointers-to-int".
You presumably wanted "myArray shall be a pointer-to-(array of three ints)". That is spelled int (*myArray)[3].
This sort of thing is much easier with typedefs.
typedef int datum[3];
datum* myArray = new datum[mySize]; // no fuss, no muss.
But seriously, just use std::vector. And make an actual struct for your group-of-three-integers. Or, if it really should behave like an array, use boost::array so that you at least get the behaviour of a first-class type.