c++ int array with values of 2 dimension int array (3d array) - c++

I'm trying to make an array which contain int[][] items
i.e
int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} };
int version1Indexes[][4] = { ...... };
int version15Indexes[][4] = { ... };
(total of 16)
int indexes[][][] = { version0Indexes,version1Indexes, .. };
anyone can suggest how to do so ?
Thanks

You can use an array of pointers to array:
int (*indexes[])[4] = { version0Indexes, version1Indexes, .. };

Either you inline your arrays inside indexes:
int indexes[][2][4] = {
{ { 1, 2, 3, 4}, {5, 6, 7, 8} },
{ {....}, {....} }
....
}
Or you make indexes an array of pointers:
int (*indexes[])[4] = { version0Indexes, version1Indexes, .... };
What you wrote in your question is not directly possible because, when used, an array variable is actually a pointer (that's why indices has to be an array of pointers).

Related

How to return a struct which contains an array pointer from a function?

I have this struct and declaration in .h file,
struct strct
{
int *arry;
};
strct func01();
and this function in .cpp file,
strct func01()
{
int temp_arry[] = {5, 6, 7, 8, 9};
strct rtrn;
rtrn.arry = temp_arry;
return rtrn;
}
and i call the function like,
strct test = func01();
printf("%d", test.arry);
It prints some random numbers. I want to print the full array.
Before we start, let's recall the behavior of the sizeof operator:
Case of : int *
int *arry;
int iSize = sizeof (arry); <-- Return size of pointer and NOT number of elements
Case of : int []
int temp_arry[] = {5, 6, 7, 8, 9};
int iSize = sizeof (temp_arry); <-- Return total memory size allocated for 5 elements
You understand now that the composition of your structure does not allow you to determine the number of elements of your int *arry struct member. Therefore, you don't know how many element you should display.
If you wish to keep your program without using the STL: vector, array, ... you must complete your structure as follows:
struct strct
{
int size; // Contains the number of elements to use
int *arry;
};
strct func01();
strct func01()
{
strct rtrn;
int tab_size = 5;
// it is a temp variable. Destroyed when function ends.You can not use it !
int temp_arry[] = {5, 6, 7, 8, 9};
// This table is allocated with new and can be used
int *permanent_arry = new int [tab_size];
for (int i=0; i<tab_size; i++)
permanent_arry[i] = i;
rtrn.arry = permanent_arry;
rtrn.size = tab_size;
return rtrn;
}
int main ()
{
strct test = func01();
for (int i=0; i<test.size; i++)
printf("%d ", test.arry[i]);
// dont forget to delete memory
delete [] test.arry;
}
First, this code is wrong because:
the lifetime of temp_arry[] is end after func01 returns.
you are printing a pointer, not an array.
Second, if you want to print the full array, you'd better redesign your code, for example, you may use vector to clean up your code. (this code needs C++ 11)
struct strct
{
std::vector<int> arry;
};
strct func01();
strct func01()
{
std::vector<int> temp_arry = {5, 6, 7, 8, 9};
strct rtrn;
rtrn.arry = temp_arry;
return rtrn;
}
strct test = func01();
for(auto i : test)
std::cout << i << " ";
Note: most of the time there's no point to use built-in arrays as return value, even though it will decay to a pointer prvalue.

Embedded C++ static initialization of struct arrays

While migrating to C++ I require a certain function that seems to have been deprecated.
sorry, unimplemented: non-trivial designated initializers not supported
What is the correct way to implement the following data storage system in C++ for memory constraint systems?
typedef union union_t {
float f;
int i;
} arg;
typedef struct type_t {
int a;
arg b;
int d;
} element;
const element list[] = {
{
.a = 1,
.b = { .f = 3.141519f },
.d = 6
},
{
.a = 3,
.b = { .i = 1 },
}
};
Often the use of std:map or std:vector is suggested. Which is suitable, however list is immutable and must be able to compile and link to a specific block of flash. Both seem unfit for that purpose.
The highest I can go is ARM Compiler 6, which is C++14.
The way you shown is almost correct compliant with the incoming C++20 standard. Only that .d also have to be initialized. Is it what I suggest to use.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0329r4.pdf
To handle this in C++14 you have to initilize it explicilty:
typedef union union_t {
float f;
int i;
} arg;
typedef struct type_t {
int a;
arg b;
int d;
} element;
const element list[] = {
{
/*.a = */ 1,
/*.b = */ { /*.f = */ 3.141519f },
/*.d = */ 6
},
{
/* .a = */ 3,
/* .b = */ { /* .i = */ 1 },
0
}
};

Initializing an array of pointers to structs in C++

Initializing an array of pointers to structs in C can be done using compound literals.
typedef struct {
int a;
int b;
} s;
In C:
s *ptrArray[] = {
&(s){
.a = 1,
.b = 2
},
&(s){
.a = 4,
.b = 5
}
};
How can this be done in C++?
I have also seen the difference in initializing structs in C++ not using compound statements:
s s1 = { a: 7, b: 8 };
First - initializing anything to the address of a temporary value seems extremely fishy, in C as well. Are you sure that's valid? Hmmm. Anyway, a C++ compiler will really not let you do that.
As for the your designated (named-field) initialization C++ line - it's actually non-standard, it's a GNU C++ extension, and you can't rely on it.
You could do this:
struct s { int a, b; };
int main() {
s data[] = { { 1, 2 }, { 4, 5 } };
// instead of ptrArray[i], use &(data[i])
}
This compiles just fine. But - a more C++'ish version of this code would be:
#include <array>
struct s { int a, b; };
int main() {
std::array<s, 2> data { s{ 1, 2 }, s{ 4, 5 } };
// instead of ptrArray[i], use &(data[i]),
// or use iterators, or ranged for loops
}
Why would you want to use std::array? Here's one explanation of the benefits. Actually, you could do slightly better and repeat yourself less with:
int main() {
auto data = make_array(s{ 1, 2 }, s{ 4, 5 });
// instead of ptrArray[i], use &(data[i]),
// or use iterators, or ranged for loops
}
The make_array function is taken from here; you also have std::experimental::make_array(), but that's not standardized yet.
If you want to add or remove elements from data at run-time, you might switch to using std::vector:
#include <vector>
struct s { int a, b; };
int main() {
std::vector<s> data { s{ 1, 2 }, s{ 4, 5 } };
// instead of ptrArray[i], use &(data[i]),
// or use iterators, or ranged for loops
}
The reason your initialize was failing is you were attempting to initialize the array of pointers to struct to the address of numeric literal constants. The same as:
#define A 5
int b = &A; /* NOT HAPPENING */
(you can't take the address of 5)
You can solve your problem by simply initializing an array of s instead of an array of pointers to s, e.g.:
s ptrarr[] = { {1, 2}, {4, 5} };
With that change, your array will initialize fine, e.g.
#include <iostream>
typedef struct {
int a;
int b;
} s;
int main (void) {
s ptrarr[] = { {1, 2}, {4, 5} };
int cnt = 0;
for (auto& i : ptrarr)
std::cout << "ptrarr[" << cnt++ << "] : " << i.a << ", " << i.b << "\n";
}
Example Use/Output
$ ./bin/ptrarrystruct
ptrarr[0] : 1, 2
ptrarr[1] : 4, 5

Returning a pointer to an array C++

I have a function that needs to return a pointer to an array:
int * count()
{
static int myInt[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
return &myInt[10];
}
inside my main function I want to display one of the ints from that array, like here at index 3
int main(int argc, const char * argv[])
{
int myInt2[10] = *count();
std::cout << myInt2[3] << "\n\n";
return 0;
}
this however gives me the error: "Array initializer must be an initializer list"
how do I create an array within my main function that uses the pointer to get the same elements as the array at the pointer?
A few problems in your code:
1) you need to return a pointer to the beginning of the array in count:
return &myInt[0];
or
return myInt; //should suffice.
Then when you initialize myInt2:
int* myInt2 = count();
You can also copy one array into the other:
int myInt2[10];
std::copy(count(), count()+10, myInt2);
Note copying will create a second array using separate memory than the first.
You don't need pointers, references are fine.
int (&count())[10]
{
static int myInt[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
return myInt;
}
int main(int argc, const char * argv[])
{
int (&myInt2)[10] = count();
std::cout << myInt2[3] << "\n\n";
return 0;
}

How to initialize pointer to pointer with premade data?

I have a pointer to a pointer, since I can't pass dynamic arrays to functions. However, if I want to initialize that pointer-to-pointer with premade data, how can I set it since {a,b,c} notation for arrays won't work for pointers?
You can do this:
static int row1[] = {1, 2, 3};
static int row2[] = {4, 5, 6, 7};
static int row3[] = {8, 9, 10, 11, 12, 13};
static int *pptr[] = {row1, row2, row3};
At this point, pptr can be assigned to an int**:
int **p = pptr;
[This answer is only relevant if you need a double*. Your question was edited to say pointer to pointer - if that's what you need, this answer is not relevant.]
You can do this instead:
double fValues[3] = { 1, 2, 3 };
The variable fValues is already a pointer - array variables without the [] are pointers to the first element of the array. This is not a dynamic array, so you don't need to allocate/free its memory.
Assuming your function that takes a double pointer looks something like this:
void Func(double* pDbl) {...}
you'd call it like this:
Func(fValues);
You can create small dynamic arrays recursively something like this:
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct
{
int* pValues;
size_t Count;
} List;
const List ListEnd = { NULL, 0 };
List NewList(int Value, List SubList)
{
List l;
l.Count = SubList.Count + 1;
if (SubList.Count == 0)
{
l.pValues = malloc(sizeof(int));
}
else
{
l.pValues = realloc(SubList.pValues, l.Count * sizeof(int));
}
if (l.pValues == NULL)
{
// do proper error handling here
abort();
}
// moving data isn't necessary if the list elements are
// in the reverse order
memmove(&l.pValues[1], &l.pValues[0], SubList.Count * sizeof(int));
l.pValues[0] = Value;
return l;
}
void PrintDynArr(int* pValues, size_t Count)
{
while (Count--)
{
printf("%d\n", *pValues++);
}
}
int main(void)
{
int* p;
PrintDynArr(p = NewList(1,
NewList(2,
NewList(3,
NewList(4, ListEnd)))).pValues,
4);
free(p);
return 0;
}
Output:
1
2
3
4