Pointer of Two dimensional array to function c++ - c++

Im kind of begginer in C++, just to programming in PHP and JAVA, I have problem to make a pointer to 2d array, then use this pointer in different function and cout values of [0] and [1].
There is part of my script.
int size_dd = 5;
int dd[size_dd][2];
for (int i = 0; i < size_dd; i ++)
{
dd[i][0] = 2 * i + 10;
dd[i][1] = 4 * i + 20;
}
I can read the dd[i][0] in main function but I cannot call them in function read(int* twodarray), as it returns int[int] and the 2nd parameter from array is lost.
Thing is that I need to make pointer to this array and call it in other function.
But the problem is when I handle *dd in to the function, it return that dd is int[int] value instead of int[int][int], how can I resolve it?

Your function should have following signature:
void fooByPtr(int(*arr)[5][6]) {
(*arr)[4][4] = 156;
}
// Call ex:
int dd[5][6];
fooByPtr(&dd);
You can also do it with reference and template:
void fooByRef(int (&arr)[5][6]) {
arr[4][4] = 156;
}
template<int N, int M>
void fooByRefTempl(int(&arr)[N][M]) {
arr[4][4] = 156;
}
Some other comments to your code (also the one from comment):
You can create arrays using constant values as sizes, so this is wrong:
int size_dd = 5;
and should be:
const int size_dd = 5;
in your fun_call you should dereference your array: (*dwu_wymiar) before indexing it.
finally, change funCall(int(*dwu_wymiar)[][2], to int(*dwu_wymiar)[5][2], as in my example above.

Related

Why can a function take (int *&) as a parameter? [duplicate]

This question already has answers here:
Difference between pointer to a reference and reference to a pointer
(6 answers)
Closed 4 years ago.
Following is a code to split an array. The
first output array will contain the input array entries in between the given two indices and the second
output array will contain the rest of the entries.
void splitArray(int *arr, int size, int ind1, int ind2,
int *&first, int &firstSize, int *&second, int &secondSize){
firstSize = ind2 - ind1 + 1;
secondSize = size - firstSize;
first = new int[firstSize];
second = new int[secondSize];
for (int i = 0; i < ind1; i++)
second[i] = arr[i];
for (int i = ind1; i <= ind2; i++)
first[i - ind1] = arr[i];
for (int i = ind2 + 1; i < size; i++)
second[i - firstSize] = arr[i];
}
The thing I can understand why it has parameters like int *&first and int *&second, arent they are same as just int first and int second but in this code they are used as pointers to dynamic arrays.
T *&foo declares a reference to a pointer to T. Don't confuse the ampersand in declarations and definitions with the address-of operator.
References to pointers are used if the called function needs to be able to modify the value of the pointer passed to it:
void bar(int *&ptr) {
ptr = 42; // change the value of the pointer (pseudo ... 42 is most likely
*ptr = 42; // change the value of the pointee not a valid pointer value)
}
// ...
int *foo = nullptr;
bar(foo);
// foo == 42;
Hint: Read types from right to left: T *& --> &* T --> reference (&) to pointer (*) to type T.

Pass 2D array of histograms to function (C++)?

In C++ in ROOT (the CERN language), I have declared a 2D array of histograms:
TH1F *hist[xlen][ylen];
where xlen and ylen are not variable-length; I assign them values in my code.
I would like to pass this 2D array into a function. I'm having trouble specifying the input parameter, however. Can someone help me out?
For an example, I can pass a 1D histogram (TH1F *hist[length];) with a function like,
void func(TH1F** Hist) {
cout<<Hist[0]<<endl;
}
Please note that although my 2D histogram has a definite size (i.e. xlen, ylen), as defined in my code, I do not want the function to be limited to arrays of a single size.
If you want to use the same function for different dimensions within the same program, the only way I see is to pass a pointer to the first element of the array together with the dimensions and then calculate each index on your own, i.e. by current_row_index * column_size + current_column_index:
void func(int rows, int columns, int **hist) {
static int arr[10] = {0,1,2,3,4,5,6,7,8,9};
for(int r=0; r<rows; r++) {
for(int c=0; c<columns; c++) {
int* aPtr = &arr[(r*columns+c)%10];
hist[r*columns + c] = aPtr;
cout << *hist[r*columns + c] << " ";
}
cout << endl;
}
}
int main() {
int *a20x10[20][10] = {};
int *a5x3[5][3] = {};
func(20,10,&a20x10[0][0]);
func(5,3,&a5x3[0][0]);
return 0;
}
/*But first of all you want to pass by reference, so a
* more correct function call might be:
*/
void Call(TH1F **Hist, size_t size_x, size_t size_y);
/* allows changing hist or setting to NULL
* in function
*/
void Call2(TH1F ***Hist, size_t size_x, size_t size_y);
/* with a call like */
int main(void)
{
TH1F *hist[xlen][ylen] = NULL;
/* malloc here/memset hist */
Call(*hist, xlen, ylen);
Call2(hist, xlen, ylen);
return (0);
}
You can do this with a template function. The template will automatically pick up the dimensions of the array.
template<int C, int R>
void func(TH1F* (&hist)[C][R])
{
cout << hist[0][0] << endl;
}
I managed to get it to work trivially by circumventing the issue: Using a vector of vectors instead of a 2D array.
The answer by Stephan seems the closest to solving it as intended, but did not work. It is also a bit too complicated for me to know how to adjust the code to make it work.

Struggling to pass an array created in one function to a sort function

I am currently working on a project where we have to create an array of 1000 elements then pass it to another function to sort it. Everything I have seen online shows you how to pass it from main to another function, but not the other way around.
Please take a look at my code and help me pass Ar[1000] from Array() to ISort and ultimately main
#include <iostream>
#include <time.h>
using namespace std;
void Array()//function to make array
{
int Ar[1000];//creating array
int i = 0;//random variable to be element #
int counter = 0;// counter variable
int randnum;//variable to old random number
srand(time(NULL));//seeding rand with time
while (counter != 1000)
{
randnum = rand();
Ar[i] = randnum;
cout << Ar[i]<<endl;
counter++;
}
}
void ISort(int Ar[1000])//Iterative sort
{
int count = 0;//another counter variable
int count2 = 0;//counter variable # 3 because nested loops
int j=0;//Temp index # similar to i
int temp; //Temp variable to help switch elements
while (count != 1000)
{
if (Ar[count] < Ar[j])
{
temp = Ar[count];
Ar[count] = Ar[j];
Ar[j] = temp;
}
}
}
/*void RSort(int Ar)//Recursive sort
{
}
*/
int main()
{
Array();
ISort();
system("Pause");
return 0;
}
Ar in your Array function will be destroyed once this function finishes, you need to have a way to prevent this, one way is to pass an array by parameter instead of making it function local variable:
void Array(int* Ar, int count)//function to make array
{
I would also change Your current ISort definition to:
void ISort(int* Ar, int acount)//Iterative sort
where acount is number of elements in Ar. This is because it makes no difference whether you use void ISort(int Ar[1000]) or void ISort(int* Ar) (read here for more on this). If you want to preserve array type then you must pass it by reference using: void ISort(int (&Ar)[1000]).
Finally changes in main:
int Ar[1000];//creating array
Array(Ar, 1000);
ISort(Ar, 1000);
system("Pause");
return 0;
working code is here: http://coliru.stacked-crooked.com/a/678f581f802da85b
You also forgot to increment count inside your sorting loop.
Your array int Ar[1000] variable inside an Array() function is a local variable. Make it a global variable by moving it out of the function scope:
int Ar[1000]; //creating array
// your functions here
int main()
{
Array();
ISort(Ar);
return 0;
}
You should also modify the Array() function to accept array as parameter as pointed out in the comments below. Please note that I am omitting the array size part as it seems the number of the elements is set to 1000:
void Array(int Ar[]){
//...
};
in which case the above code would be:
int Ar[1000]; //creating array
// your functions here
int main()
{
Array(Ar);
ISort(Ar);
return 0;
}
Change the Array function declaration to:
int* Array() and make it return the array Ar. And in main get the returned value from Array function like this:
int* Ar = Array();
and pass it to the function ISort like this : ISort(Ar);.
Here is an example on SO passing an array to a function.
The easiest solution would be to change Array function a bit:
int* Array() { // change return type to be able to return array you create
int Ar[1000];
for (int i = 0; i < 1000; i++) { // much better to use for loop than while
Ar[i] = rand(); // no need to hold another variable for random number
cout << Ar[i] << endl;
}
return Ar; // return the Ar
}
int main() {
int* array = Array();
ISort(array);
}
Hope that helps. Also there are many other solutions to this but I don't know what exact restrictions your task has. If you have any questions feel free to ask.
EDIT: So I totally forgot about that C arrays are just a plain old pointers... Well then the solution would be like this:
void Array(Ar[1000]& array) { // pass array to the function with reference
for (int i = 0; i < 1000; i++) { // much better to use for loop than while
array[i] = rand(); // no need to hold another variable for random number
cout << array[i] << endl;
}
}
int main() {
int[1000] array = Array();
ISort(array);
}
Sorry for the error but using C style arrays really isn't common in C++ when you can use vectors and maps.

C++ 2D dynamic array crash

Hi I'm having some problem with 2D dynamic array.
int main()
{
double **M;
int M_dimension;
int i;
M_dimension = 10;
M = new double *[M_dimension];
for (i=0;i<M_dimension;i++)
{
M[i] = new double[M_dimension];
}
M[0][0] = 1.0;
...
}
Program works but I'd like to initialize 2D array using such a function:
void initialize2D(double **M,int M_dimension)
{
int i;
M = new double *[M_dimension];
for (i=0;i<M_dimension;i++)
{
M[i] = new double[M_dimension];
}
}
Finally the program looks like this:
int main()
{
double **M;
int M_dimension;
int i;
M_dimension = 10;
initialize2D(M,M_dimension);
M[0][0] = 1.0; //crash
...
}
Unfortunately it crashes at M[0][0] = 1.0;
Thanks for any help or suggestions.
You are passing M by value, instead of by reference. initialize2D needs to change the value of the pointer-to-pointer M such that it points to the memory allocated
Try changing your function signature to this instead:
void initialize2D(double **&M,int M_dimension)
Or
void initialize2D(double ***M,int M_dimension) {
...
*M = new double *[M_dimension];
...
}
You need to pass a reference to double** instead of double** to function, otherwise the modification done to a pointer after assigning M the reslut of new get lost on exit from a function.
what the problem might be is where you declaring an integer parameter such as int M_dimension
void initialize2D(double **M,int M_dimension)
and then you initializing the dynamic array as:
M[i] = new double[M_dimension];
where it comes to contradiction because you declared the variable M_dimension as an integer and then you using it as a double
try it this way:
either change the data type of array or the M_dimension, so then both of them have the same data type.
hopefully this will help you out
Why don't you use std::vector or Boost.MultiArray
It would be quite easy exercise to define 2-dimension array as generic vector of vectors in C++

Passing Pointer To An Array Of Arrays Through Function

There is a pointer-to-an-Array of Arrays i.e. NameList in the code. I want the contents of each of the Arrays in the Pointer(NameList) to get printed one by one. The below code is not able do the task. Pls. help.
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
main()
{ Function(NameList); }
Function(int *ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 2; j++)
{
//It does not print the data
printf("\nName: %s", ArrayPointer[index++]);
}
index=0; //Counter reset to 0
ArrayPointer++; //Pointer is incremented by one to pick next array in the pointer
}
}
print("code sample");
Another note from the original poster of the question:
I have completed a pacman game in Turbo C. I was polishing some graphics routines so that it can be reused again easily. This is only a small sample created for the purpose of help and understanding the concept. All data in the code actually are char arrays for sprites. Now i simply want to call a function passing the pointer so that each arrays in the pointer are drawn to the screen. How can this code be modified to handle this? Im actually stuck up here.
Darn it litb, once again you beat me to the punch by mere minutes. (If only I didn't have kids who keep waking up...)
Ahh, what the hell. Perhaps this will still be useful to somebody.
Oh, and just to nail this thing down:
Arrays, such as int a[4] allocate memory space for their data.
Pointers, such as int * p allocate just enouch memory space for a pointer to another spot in memory.
That's why we can use sizeof on arrays and get the full memory footprint, but not on pointers.
Other than that little distinction, there really isn't a big difference between int[] and int*. (Consider how many folks declare *main(int argc, char **argv) vs main(int argc, char * argv[]).)
ATTENTION: All memory addresses here are fictional. I'm just making them up to illustrate a point.
Given:
int Data1[] = {10,11};
int Data2[] = {20,22};
int Data3[] = {30,33};
We now have 3 blocks of memory. Say:
0xffff0000-0xffff0003 with a value of (int)(10)
0xffff0004-0xffff0007 with a value of (int)(11)
0xffff0008-0xffff000b with a value of (int)(20)
0xffff000c-0xffff000f with a value of (int)(22)
0xffff0010-0xffff0013 with a value of (int)(30)
0xffff0014-0xffff0017 with a value of (int)(33)
Where:
Data1 == & Data1 [0] == 0xffff0000
Data2 == & Data2 [0] == 0xffff0008
Data3 == & Data3 [0] == 0xffff0010
NO, I'm not going to get into big-endian vs little-endian byte ordering here!
Yes, in this case, Data1[2] == Data2[0]. But you can't rely on your compiler laying things out in memory the same way I've laid them out here.
Next:
int *NameList[] = {Data1, Data2, Data3};
So we now have another block of memory. Say:
0xffff0018-0xffff001b with a value of (int*)(0xffff0000)
0xffff001c-0xffff001f with a value of (int*)(0xffff0008)
0xffff0020-0xffff0023 with a value of (int*)(0xffff0010)
Where:
NameList == & NameList [0] == 0xffff0018
Note that NameList is of int ** type, and NOT int* type!
We can then write:
void Function(int **ArrayPointer)
{
for ( int i=0; i < 3; i++ )
for ( int j=0; j < 2; j++)
printf("Name: %d\n", ArrayPointer[i][j] );
}
int main() { Function(NameList); }
ArrayPointer resolves to (int**)0xffff0018.
ArrayPointer[0] == *( (int**) 0xffff0018 ) == (int*)(0xffff0000) == Data1.
ArrayPointer[0][1] == *( ( * (int**) 0xffff0018 ) + 1 ) == (int) * ( (int*)0xffff0000 + 1 ) == (int) * (int*) 0xffff0004 == Data1[1].
You may want to review pointer arithmetic: array[N] == *( array + N )
main has to return a type. You forget to put "int" as a return type (implicit int in C++ is banned).
Having said that, i'm not sure what you mean by
// It does not print the data
printf("\nName: %s", ArrayPointer[index++]);
ArrayPointer[index++] would, as it is defined in the parameter list, return an int. How is that supposed to store a name ? It will store an integer!
Once again, that said, you can't call that Function (pun intended) with that particular argument. Let's view your types:
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
Data1 Data2 Data3 NameList
int[2] int[2] int[2] int*[3]
Contrary to what you said, NameList is not a pointer to an array of arrays. I feel i need to show you what that would be:
int (*NameList)[N][M] = Some3DimensionalArray;
That wouldn't make sense at all. So what do you have?
Data1 = array of 2 int
Data2 = array of 2 int
Data3 = array of 2 int
NameList = array of poiners to int
That is what you got. And you pass NameList to a Function that wants a pointer to an int. It must fail already at the time you call Function in main! I've got no idea what you mean by name in that line in Function. But if you want to print out the integers that are stored in the arrays pointed to (by pointers to their first element), you can do it like this (keeping your code as much as i can):
// don't forget the return type, mate. Also see below
void Function(int **ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 2; j++)
{
// It does not print the data. It is not a string,
// but an int!
printf("\nName: %d\n", ArrayPointer[i][index++]);
}
index=0; //Counter reset to 0
// no need to increment the pointer. that's what the indexing by i
// above does
// ArrayPointer++;
}
}
I keep preaching people asking questions the difference between a pointer and an array. It's crucial to write correct code. I hope i could help. At the end, just a little though about the difference between int[] and int*. The first is an incomplete array type, while the second is a complete type (pointer to int):
typedef int Single[]; // array of indeterminate size.
typedef int *Pointer; // pointer to int
Single s1 = { 1, 2, 3, 4 }; // works!
Pointer s2 = { 1, 2, 3, 4 }; // no no, doesn't work. s2 wants an address
s2's type now has a type different from int[], because you initialized the array which would have incomplete type, the array s1 become complete after defined. It has type of int[4]. In parameter lists, however, there exist a special rule, which will cause any array type (even complete ones!) to be equivalent to a pointer to their first argument. Thus:
void f(int *a) <=> void f(int a[]) <=> void f(int a[42]);
void f(int (*a)[42]) <=> void f(int a[][42]) <=> void f(int a[13][42])
// ...
That's because you can't pass arrays by value. The compiler abuses that to make array types equivalent to pointers to their first element. Same deal with functions:
void f(int a()) <=> void f(int (*a)())
Because you can't pass functions by value (huh, doesn't even make sense at all to me), the compiler abuses it to make a function type in a parameter list equivalent to a pointer to that function type.
int Data1[]
has the type of
int *
and
int *NameList[]
has the type of
int **
You have a two-dimensional array there. Most likely you meant:
Function(int **ArrayPointer)
On that note, ANSI C/C89/C99 functions have an explicit return type (or void), e.g.
int main() { ... }
void Function() { ... }
The value pointed to by ArrayPointer is an int, not a string. Thus
printf("\nName: %s", ArrayPointer[index++]);
Should be written as something else.
A third thing: index == j in your code. Thus index can be removed in favor of j.
i and j are probably not good variable names here because ArrayPointer is not name describing a list of something.
If you need more help, please post what you're looking to do, because you code has several bugs (and oddities) in it.
Judging by your "answer" (you really should have edited your original post and added this information), you probably want something like this:
void draw_all_sprites(Sprite *sprites, size_t num_sprites)
{
Sprite *cur_sprite;
size_t i;
for(i = 0; i < num_sprites; ++i)
{
draw_sprite(cur_sprite);
++cur_sprite;
}
}
A fairly simple for loop to iterate through elements in an array.
Paramod,
is there a function you need to call that takes something along the lines of
void drawSprite(int *data, int rows, int cols)
?
Then you need to have all data in a single chunk of memory. In your example, the compiler allocates a separate chunk for every row, and then another chunk to hold the three pointers to rows. Thus, the array is kept in 4 different places.
What you need is a multidimensional array rather than array of arrays. Initialize your data like this:
int data[3,2] = {{10,10},{20,20},{30,30}};
Then you can call your function like this:
drawSprite(&data[0,0], 3, 2);
Using multidimensional array places all elements in one block of memory. The advantage is, you can pass the piointer to first element, and you know where all other elements are. The disadvantage - all rows are allocated the same size.
I made some corrections in your program please find them and compare. I know its too late for the response. But I saw this today itself.
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
main()
{
Function(NameList);
}
Function(int *ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 5; j++)
{
//It does not print the data
printf("\nName: %d\n", *((int *)ArrayPointer[i] + index));
index++;
}
index=0; //Counter reset to 0
}
}
Explanation:
When you pass NameList to Function as a pointer to an integer, what gets passed is the address of the first element of the array, which happens to be Data1 (an address to an array). But since this address is held in an array of ints, it will be considered as an integer. To make it behave like an address to an array(or, for that matter pointer to an int) you need to cast it to (int *). Thats what I did in :
printf("\nName: %d\n", *((int *)ArrayPointer[i] + index));