Been awhile since I've programmed in C++ however I have a slight problem that I'm trying to figure out.
Is it possible to make a 2 by 2 dynamic array where 1 dimension is not dynamic?
For example
array[2][Dynamic]?
It seems like a waste to make array[dynamic][dynamic] and when I only need to use the first [0][dynamic] and second [1][dynamic] values.
Should I use another data structure?
Thanks.
Arrays and pointers are basically equivalent, so you can achieve this with an array of pointers:
int* array[2];
array[0] = new int[x];
array[1] = new int[y];
You can still access it as you would multidimensional array:
array[0][x-1] = z;
This works in C++11:
std::array<std::vector<MyClass>,2> arr;
Or you could use a c-style array of vectors
std::vector<MyClass> arr[2];
Sure but it has to be dynamic in the first dimension.
Like this for instance
typedef int two_int_array[2];
two_int_array* a = new two_int_array[n];
for (int i = 0; i < n; ++i)
{
a[i][0] = 1;
a[i][1] = 2;
}
Of course the better way in general is to use vectors. Since you can't have a vector of arrays, a vector of structs might be better for your case.
struct two_int_struct
{
int value[2];
};
std::vector<two_int_struct> a(n);
for (int i = 0; i < n; ++i)
{
a[i].value[0] = 1;
a[i].value[1] = 2;
}
Related
Let's assume that we have a simple struct
struct S {
int a;
int b;
int c;
}
Now we want to create an array of pointers (2d array 5x5):
S** arr = new S*[5];
for (int i = 0; i < 5; ++i)
arr[i] = new S[5];
My questions are:
Is it a correct way to dynamically allocate a memory for this array using new? Shouldn't we use sizeof(S) somewhere?
How would the code look like if using malloc instead of new? Is the code below correct?
S** arr = (S**)malloc(5 * sizeof(S));
for (int i = 0; i < 5; ++i)
arr[i] = (S*)malloc(5 * sizeof(S));
Yes, this is correct way. No, there is no need to use sizeof(S)
Your code isn't correct. Generally you shouldn't use malloc if struct S have non-trivially-copiable members, but if S satisfy that, your code should look like this:
S** arr = (S**)malloc(5 * sizeof(S*));
for (int i = 0; i < 5; ++i)
arr[i] = (S*)malloc(5 * sizeof(S));
But using malloc in C++ is considered as bad practice. And I would try to rewrite it using std::vector if you can.
And of course don't forget to clear memory with delete/free in case of using new/malloc
On a project I'm working on, I need some dynamic allocation due to the size of the used data not been known in advance. std::vector seems perfect for this use case. However, due to the software environnement, I can not use "modern" C++ in the headers. I would like to convert this vectors array to be used in fuction with compliant headers.
Quick example:
void func(int tab[][]/*Vector can not be used here*/){/*Do things*/}
int main(){
std::vector<int> vecTab[6/*Fixed, prior known, dimension*/];
//Adding a random number of values in each vector (equal number in each one)
//Transformation of vecTab
func(vecTabMod);
return 1;
}
There is a lot of similar questions on this site, none of them really adressing bi-dimensionnal arrays.
Bonus point: no reallocation, access through pointers
You'll need to copy the data pointers into a separate array so that the type and layout matches what the funciton expects. This can be done without heap allocation since the size of this array is fixed.
int* vecTabMod[6];
std::transform(std::begin(vecTab), std::end(vecTab), std::begin(vecTabMod),
[](auto& v) { return v.data(); });
func(vecTabMod);
std::vector is worst choice for this soultion!
Using dynamic arrays is better.
Anyway you can use this code:
#include <vector>
#include <iostream>
int func(uint32_t firstDimensionSize, uint32_t* secoundDimensionSizes, int** tab){
int sum = 0;
for(uint32_t i = 0; i < firstDimensionSize; i++){
for(uint32_t j = 0; j < secoundDimensionSizes[i]; j++){
sum += tab[i][j];
}
}
return sum;
}
int main(){
std::vector<int> vecTab[6];
vecTab[0].push_back(2);
vecTab[0].push_back(5);
vecTab[3].push_back(43);
// Calculate count of elements in non dynamically arrays
uint32_t firstDimensionSize = (sizeof(vecTab) / sizeof((vecTab)[0]));
uint32_t* secoundDimensionSizes = new uint32_t[firstDimensionSize];
int**tab = new int*[firstDimensionSize];
for(uint32_t i = 0; i < firstDimensionSize; i++){
secoundDimensionSizes[i] = vecTab[i].size();
tab[i] = &(vecTab[i][0]);
}
std::cout << func(firstDimensionSize, secoundDimensionSizes, tab) << std::endl;
delete[] secoundDimensionSizes;
delete[] tab;
system("pause");
}
Don't kill me: I'm a C++ noob.
Here's the code:
const int lengthA = 3;
const int lengthB = 4;
int main() {
double matrix[lengthA][lengthB];
double temp[lengthB];
for (int i = 0; i < lengthB; i++) {
temp[i] = i;
}
matrix[1] = temp;
}
How can I assign an array to a fixed index of a matrix that can contain it? Should I iterate each item on each (sequential) position? I hope I can simple past chunk of memory...
You don't directly assign raw arrays but rather copy their contents or deal with pointers to arrays
int main() {
double* matrix[lengthA]; // Array of pointers, each item may point to another array
double temp[lengthB]; // Caveat: you should use a different array per each row
for (int i = 0; i < lengthB; i++) {
temp[i] = i;
}
matrix[1] = temp;
}
Keep in mind that this is not a modern C++ way of doing things (where you could be better off using std::array or std::vector)
You can not, arrays are not assignable.
Here are three possible way to solve it:
Use std::array (or std::vector) instead
Copy the elements from one array to the other (either through std::copy, std::copy_n or std::memcpy)
Make matrix an array of pointers instead
I recommend std::array (or std::vector) first, copying second, and using pointers only as a last resort.
You can use double *matrix[lengthB]; instead of double matrix[lengthA][lengthB];
I'm using c++ and I want to use two dimensional dynamic array. I tried this:
#include<iostream.h>
using namespace std;
void main(){
int const w=2;
int size;
cout<<"enter number of vertex:\n";
cin>>size;
int a[size][w];
for(int i=0; i<size; i++)
for(int j=0; j<w; j++){
cin>>a[i][j];
}
}
but not worded.
and I tried this:
int *a = new a[size][w];
instead of
int a[size][w];
but not worked!
could you help me plz.
thanks a lot.
The correct approach here would be to encapsulate some of the standard containers, that will manage memory for you, inside a class that provides a good interface. The common approach there would be an overload of operator() taking two arguments that determine the row and column in the matrix.
That aside, what you are trying to create manually is an array of dynamic size of arrays of constant size 2. With the aid of typedef you can write that in a simple to understand manner:
const int w = 2;
typedef int array2int[w];
int size = some_dynamic_value();
array2int *p = new array2int[size];
Without the typedef, the syntax is a bit more convoluted, but doable:
int (*p)[w] = new int [size][w];
In both cases you would release memory with the same simple statement:
delete [] p;
The difference with the approaches doing double pointers (int **) is that the memory layout of the array is really that of an array of two dimensions, rather than a jump table into multiple separately allocated unidimensional arrays, providing better locality of data. The number of allocations is lower: one allocation vs. size + 1 allocations, reducing the memory fragmentation. It also reduces the potential from memory leaks (a single pointer is allocated, either you leak everything or you don't leak at all).
For a dynamic sized array you must dynamically allocate it. Instead of
int *a = new a[size][w];
Use
int** a = new int*[size];
for(int i = 0; i < size; i++)
a[i] = new int[w];
OP is saying he wants to create a 2 dimensional array where one dimension is already known and constant and the other dimension is dynamic.. Not sure if I got it right but here goes:
int main() {
const int w = 2;
int size = 10;
int* arr[w];
for (int i = 0; i < w; ++i)
arr[i] = new int[size];
//do whatever with arr..
//std::cout<<arr[0][0];
for (int i = 0; i < w; ++i)
for (int j = 0; j < size; ++j)
std::cout<<arr[i][j];
for (int i = 0; i < w; ++i)
delete[] arr[i];
return 0;
}
You can not do that in c++, please read about dynamic memory allocation
the code below should work
int* twoDimentionalArray = new [size*w]
I'm having problem with creating my 2D dynamic array in C++. I want it to have dynamic number (e.g. numR) of "rows" and fixed (e.g. 2) number of "columns".
I tried doing it like this:
const numC = 2;
int numR;
numR = 10;
double *myArray[numC];
myArray = new double[numR];
Unfortunately, it doesn't work. Is it possible to do it in such a way?
Of course I could use double **myArray and initialize it as if both dimensions are dynamic (with numC used as limiter in loop) but I would like to avoid it if possible.
Thanks in advance.
Is it possible to do it in such a way?
Yes:
double (*myArray)[numC] = new double[numR][numC];
// ...
delete[] myArray;
This may look a little unusual, but 5.3.4 ยง5 clearly states:
the type of new int[i][10] is int (*)[10]
Note that many programmers are not familiar with C declarator syntax and will not understand this code. Also, manual dynamic allocation is not exception safe. For these reaons, a vector of arrays is better:
#include <vector>
#include <array>
std::vector<std::array<double, numC> > vec(numR);
// ...
// no manual cleanup necessary
Replace std::array with std::tr1::array or boost::array, depending on your compiler.
Why not use a std::vector, and take advantage of its constructor:
std::vector<std::vector<int> > my2Darray(2, std::vector<int>(10));
my2Darray[0][0] = 2;
There needs to be a loop since you need to create an array for every column.
I think what you're after is:
double *myArray[numC];
for (int i = 0; i < numC; i++) {
myArray[i] = new double[numR];
}
// some code...
// Cleanup:
for (int i = 0; i < numC; i++) {
delete [] myArray[i];
}
This declares an array of pointers (to double) with numC elements, then creates an array of doubles with numR elements for each column in myArray. Don't forget to release the memory when you're done with it or you'll have memory leaks.
Your indexes should be row, then column.
double** myArray = new double*[numR];
for( unsigned int i = 0; i < numR; i++ ) {
myArray[i] = new double[numC];
}
Access row 2, column 5:
myArray[2][5];