2d Array to a function expecting int** array as parameter - c++

I want to use a function made for dynamic arrys for an pre-initialised array too.
int MinInRow(int** fieldArray, int value, int currentColumn, int maxNumColumns)
{
int minVal = 0;
for (int inkrCol = 0; inkrCol < maxNumColumns; inkrCol++)
{
if (feldArray[currentColumn][inkrSpalte] < value)
{
minVal = feldArray[currentColumn][inkrCol];
}
}
return minVal;
}
So if I try
int testArray[3][4] =
{ {4,5,6,7},
{0,1,2,3},
{9,8,10,11}, };
int (*bufferArray)[4] = testArray;
or...
int** bufferArray = testArray;
or...
...
int main()
{
/*
read in other needed parameters
....
*/
std::cout << MinInRow((*bufferArray)[4], int value, int currentColumn, int maxNumColumns);
retrun 0;
}
I cant compile. But shouldnt int** bufferArray = testarray; just work fine? I mean there is always an double pointer to the first address of an 2D-Array.
how can I hand it over to the MinInRow-function? Thanks!

There is a little problem. "*" That one tell you that you want to make a pointer, but a pointer doesn't want a variable, he want the address. And then you've written
int** bufferArray = testarray.
You should write
int* bufferArray = new int [size of array] It's for 1D array
and ....
int** bufferArray = new int* [rows];
for (size_t = 0 ; i != rows ; ++i){
bufferArray[i] = new int [colons];
}
for 2D array
"I cant compile. But shouldnt int** bufferArray = testarray; just work fine? I mean there is alway an double pointer to the first address of an 2D-Array."
And Yes, it will be work nice. If testarray already 2D array

Related

A Function returning an array from 1 int input

I made a function the returns an array like so
void array_function(int i){
int* a = NULL;
a = new int[3];
a = {i-1, i, i+1};
return a;
}
Now I want to call this function in the a new function
int main(){
int n = 3
for(int i = 0; i < n; i++){
//call the function
}
}
I am not sure how I can call the function to give me the array, any help will be appreciated
Use std::array instead. It has more friendly value semantics:
#include <array>
std::array<int, 3> array_function(int const i) {
return {{ i - 1, i, i + 1 }};
}
int main() {
for(int i = 0; i < 3; i++){
auto arr = array_function(i);
// Use array
}
}
First your function is void, which translates as no-return-function. Make it return int* like
int* array_function(int i)
Now, to call the function you need to assign it to a temporary variable, which you can do work and then you should delete it. Full code:
int* array_function(int i){
int* a = new int[3];
a[0] = i-1, a[1] = i, a[2] = i+1;
return a;
}
int main(){
int n = 3;
for(int i = 0; i < n; i++){
int* a = array_function(i); // if you are going to do something with this array, which you will
// some work with a
delete[] a; // delete it to release memory from heap, everytime you do new, you should use delete at the end of your program
}
}
You want something like this to create the array, since the method in your question does not have a return type assigned (void means that it returns nothing), you have to define a return type for the method to work, in this case a pointer to an array:
int* array_function(int i){
int* a = NULL;
a = new int[3];
a = {i-1, i, i+1};
return a;
}
And then just store the result of the method in a local variable like this:
int* myArray = array_function(n);

C++: Template argument list

I am trying to create a program that will take an original array, create one that is twice as large, and then have the original values appear twice.
I am pretty sure my code for the function is correct, but I cannot figure out what I need to put in main to make it work. I am currently getting "Expected '(' for function-style cast or type construction" and "Cannot refer to class template 'array' without a template argument list" compiler errors.
Any ideas on what I need to fix to make this work?
void repeatArray(double **array, int size)
{ //Dynamically allocate array that holds an amount of elements = size
double *resize = new double[size * 2];
for (int i = 0; i < size; i++)
{
resize[i] = (i + 1) * 2;
delete [] *array;
*array = resize;
}
}
int main()
{
const int size = 5;
**array[] = {1.1, 2.2, 3.3, 4.4};
repeatArray(double **array, size);
for (int i; i < size; i++)
{
cout << array;
}
}
You are trying to allocate a one dimensional array and make a pointer pointer point to the data that is allocated for a one dimensional array, also you are calling the wrong delete on memory allocated for a one dimensional array.
If the goal is to double the size of an array that you have allocated dynamically using new, then you can do the following
void resizeArray(int** arr, int new_size) {
delete[] (*arr);
*arr = new int[new_size];
// do your initialization here
}
int main() {
const int size = 5;
int* arr = new int[5];
resizeArray(&int, 5);
}
Although keep in mind that when you are working with dynamic arrays. It is almost always better to use std::vector than to roll your own arrays.
In C++14
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template<typename T>
void repeatArray(std::vector<T> &array) {
int element_count = array.size();
array.resize(2*element_count);
for (int i=0; i<element_count; i++)
array[i+element_count] = array[i];
}
int main() {
vector<float> array = {1.1, 2.2, 3.3, 4.4};
repeatArray(array);
for (auto &i : array) {
cout << i << ",";
}
}

Reference to non-object array from class

Let's say my function had array passed in it like this:
int someFunction ( SomeClass * const * array, int arr_size ) { }
This is array of some structures:
struct SomeStruct {
int value;
int value2;
};
What I'm trying to achieve is making a reference inside of object declared in that function:
int someFunction ( SomeStruct * const * array, int arr_size )
{
NewClass newclass (array, arr_size);
}
my constructor would look like this:
Newclass::NewClass( SomeStruct * const * array, int arr_size )
{
SomeStruct ** myReference = new SomeStruct * [arr_size];
for (int i = 0; i < arr_size; ++i)
{
myReference[i] = array[i];
}
myReference[0] -> value = 10;
}
Now, if I want to print out value of first element in array, I get just zero.
int someFunction ( SomeStruct * const * array, int arr_size )
{
NewClass newclass (array, arr_size);
cout << array[0] -> value << endl;
}
Output:
0
Is it even possible to refer to non-object from class? How do I get my reference array to change the source array? I had the reference array in that function as a non object before and everything worked fine. And no, I can't just leave it there.
When you're allocating the struct pointers in Newclass::NewClass(), you're forgetting to actually initialize those pointers to point to the actual structs.
You need:
Newclass::NewClass(SomeStruct* const* array, int arr_size)
{
SomeStruct** myReference = new SomeStruct*[arr_size];
for (int i = 0; i < arr_size; ++i) {
myReference[i] = array[i];
}
myReference[0]->value = 10;
}
Though I must say I'm confused about all the pointer indirection and why you need it. And you're leaking memory too; you never delete[] myReference.
And you should consider using std::vector instead of doing all that memory management manually.

3D multidimensional array to "row" pointer

I was wondering how i can access multidimensional rows in a 3D via pointer like this:
int ccc[8][7][2] = ....;
for(int i=0;i<8;i++)
{
int** cc_i = ccc[i];
for(int j=0;j<7;j++)
{
int* c_j = cc_i[j];
int th0 = c_j[0];
int th1 = c_j[0];
}
}
You can't, because a pointer to a pointer is not the same as an array of arrays. The layout in memory is radically different.
You can however declare e.g. cc_i as a pointer to an array, like
int (*cc_i)[2] = ccc[i];
Like this
int ccc[8][7][2] = ....;
for(int i=0;i<8;i++)
{
int (*cc_i)[2] = ccc[i];
for(int j=0;j<7;j++)
{
int *c_j = cc_i[j];
int th0 = c_j[0];
int th1 = c_j[0];
}
}

How to allocate a 2D array of pointers in C++

I'm trying to make a pointer point to a 2D array of pointers. What is the syntax and how would I access elements?
By the letter of the law, here's how to do it:
// Create 2D array of pointers:
int*** array2d = new (int**)[rows];
for (int i = 0; i < rows; ++i) {
array2d[i] = new (int*)[cols];
}
// Null out the pointers contained in the array:
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
array2d[i][j] = NULL;
}
}
Be careful to delete the contained pointers, the row arrays, and the column array all separately and in the correct order.
However, more frequently in C++ you'd create a class that internally managed a 1D array of pointers and overload the function call operator to provide 2D indexing. That way you're really have a contiguous array of pointers, rather than an array of arrays of pointers.
It depends. It can be as simple as:
int main()
{
int* data[10][20]; // Fixed size known at compile time
data[2][3] = new int(4);
}
If you want dynamic sizes at runtime you need to do some work.
But Boost has you covered:
int main()
{
int x;
int y;
getWidthAndHeight(x,y);
// declare a 2D array of int*
boost::multi_array<int*,2> data(boost::extents[x][y]);
data[2][3] = new int(6);
}
If you are fine with jagged arrays that can grow dynamically:
int main()
{
std::vector<std::vector<int*> > data;
data.push_back(std::vector<int*>(10,NULL));
data[0][3] = new int(7);
}
Note: In all the above. I assume that the array does not own the pointer. Thus it has not been doing any management on the pointers it contains (though for brevity I have been using new int() in the examples). To do memory management correctly you need to do some more work.
int *pointerArray[X][Y];
int **ptrToPointerArray = pointerArray;
That's how you make a true (contiguous in memory) multidimensional array.
But realize that once you cast a multidimensional array to a pointer like that, you lose the ability to index it automatically. You would have to do the multidimensional part of the indexing manually:
int *pointerArray[8][6]; // declare array of pointers
int **ptrToPointerArray = &pointerArray[0][0]; // make a pointer to the array
int *foo = pointerArray[3][1]; // access one element in the array
int *bar = *(ptrToPointerArray + 3*8 + 1); // manually perform row-major indexing for 2d array
foo == bar; // true
int *baz = ptrToPointerArray[3][1]; // syntax error
double** array = new double*[rowCnt];
for (int row = 0; row < rowCnt; ++row)
array[row] = new double[colCnt];
for (int row = 0; row < rowCnt; ++row)
for (int col = 0; col < colCnt; ++col)
array[row][col] = 0;
You could try Boost::MultiArray.
Check out this page for details.
:)
I had these once in a piece of code I wrote.
I was the laughing stock of the team when the first bugs leaked out. On top of that we use Hungarian notation, leading to a name like papChannel - a pointer to an array of pointers...
It's not nice. It's nicer to use typedefs to define a 'row of columns' or vice versa. Makes indexing more clear, too.
typedef int Cell;
typedef Cell Row[30];
typedef Row Table[20];
Table * pTable = new Table;
for( Row* pRow = *pTable; pRow != *pTable+_countof(*pTable); ++pRow ) {
for( Cell* pCell = *pRow; pCell != *pRow + _countof(*pRow); ++pCell ) {
... do something with cells.
}
}
You can define a vector of vectors:
typedef my_type *my_pointer;
typedef vector<vector<my_pointer> > my_pointer2D;
Than create a class derived from my_pointer2D, like:
class PointersField: public my_pointer2D
{
PointsField(int n, int m)
{
// Resize vectors....
}
}
PointsField pf(10,10); // Will create a 10x10 matrix of my_pointer
I prefer to use the () operator. There are lots of reasons for this (C++ FAQs 13.10). Change the internal representation to a std::vector if you like:
template <class T, int WIDTH, int HIEGHT>
class Array2d
{
public:
const T& operator ()(size_t col, size_t row) const
{
// Assert col < WIDTH and row < HIEGHT
return m_data [( row * WIDTH + col)];
}
T& operator ()(size_t col, size_t row)
{
// Assert col < WIDTH and row < HIEGHT
return m_data [( row * WIDTH + col)];
}
private:
T m_data[WIDTH * HIEGHT];
};
You can use it like this:
Array2d< Object*, 10, 10 > myObjectArray;
myObjectArray(5,6) = new Object();
See my code. It works on my FC9 x86_64 system:
#include <stdio.h>
template<typename t>
struct array_2d {
struct array_1d {
t *array;
array_1d(void) { array = 0; }
~array_1d()
{
if (array) {
delete[] array;
array = 0;
}
}
t &operator[](size_t index) { return array[index]; }
} *array;
array_2d(void) { array = 0; }
array_2d(array_2d<t> *a) { array = a->array; a->array = 0; }
void init(size_t a, size_t b)
{
array = new array_1d[a];
for (size_t i = 0; i < a; i++) {
array[i].array = new t[b];
}
}
~array_2d()
{
if (array) {
delete[] array;
array = 0;
}
}
array_1d &operator[](size_t index) { return array[index]; }
};
int main(int argc, char **argv)
{
array_2d<int> arr = new array_2d<int>;
arr.init(16, 8);
arr[8][2] = 18;
printf("%d\n",
arr[8][2]
);
return 0;
}
Effo UPD: a response to "Isn't that an array of pointers to arrays?", adding the example of array of pointers, very simple:
int main(int argc, char **argv)
{
array_2d<int*> parr = new array_2d<int*>;
int i = 10;
parr.init(16, 8);
parr[10][5] = &i;
printf("%p %d\n",
parr[10][5],
parr[10][5][0]
);
return 0;
}
Did I still misunderstand your question?
And you could even
typedef array_2d<int*> cell_type;
typedef array_2d<cell_type*> array_type;
int main(int argc, char **argv)
{
array_type parr = new array_type;
parr.init(16, 8);
parr[10][5] = new cell_type;
cell_type *cell = parr[10][5];
cell->init(8, 16);
int i = 10;
(*cell)[2][2] = &i;
printf("%p %d\n",
(*cell)[2][2],
(*cell)[2][2][0]
);
delete cell;
return 0;
}
It also works on my FC9 x86_64 system.