Pointers and array passing...

I am trying to pass an array to a function but i cant get it to work properly
i keep getting "cannot convert ‘double*’ to ‘double* (*)[3]’ for argument ‘1’ to ‘double picon(double* (*)[3], int)’" error on line 62

I have tried multiple ways to fix it but keep getting the same type of error

I'm sure it's something very simple and I just cant see it...


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

#include<iostream>	
#include<cmath>
#include<string>
#include<fstream>
#include<vector>
using namespace std;

//======================================================================
//				Functions 
//======================================================================

double picon (double* data [][3], int l){

	double num;
	double ans = 1;
	int x;
	for (x=0 ; x<l ; ++x){
		num = 1 / (*data[x][2] * sqrt(2*3.14159265359));
		ans = ans * num ;
	}
return (ans);

}

int main () { 

//FILLING DATA ARRAYS 
// ask user for dat file
 
	ifstream dat;
	do {
		cout << "Input filename where the raw data exist-->";
		char filename [50];
		cin.getline(filename,50);
		dat.open(filename);
		if (!dat.is_open())
		cout << "File Does Not Exist!" << endl ;
	} while (!dat.is_open());

	double (*data)[3]= new double [15][3];

	int x = 0 ;
	int l = 0 ;
	double  a,b,c,d,e,f;

	while (	dat >> a >> b >> c){

		data[x][0] = a;
		data[x][1] = b;
		data[x][2] = c;

		cout << data[x][0] << endl; // to check
		x++;
		l++;
	}
	
	dat.close();


	double pisum ;
	pisum = picon(data, l); 
	cout << pisum << endl;

return (0);
}
data in main is a pointer to an array of 3 doubles.

data in picon is a pointer to an array of 3 pointers to double.

You probably want to change line 13 to
double picon (double data[][3], int l){
or
double picon (double (*data)[3], int l){ (same thing).
let's look at the argument of picon:
double* data [][3]

when you define an array, you're actually defining a pointer to the first element in it, and allocating memory for it in compile time.
pointer -> values

when you define a 2D array, you're actually defining a pointer to a 1D array of pointers, each one points to a 1D array of values.
pointer -> pointers -> values
this a 2 level pointer

the argument above is a pointer to a 2D array, means it's a:
pointer -> pointers -> pointers -> values
this is a 3 level pointer

when you called picon() -line 62-, you sent to it data, which is a 2D array:
pointer -> pointers -> values
this is a 2 level pointer.

the compiler tries to convert data to the correct 3 level pointer, problem is.... C++ cannot convert double** to double***

i think what you mean to do is:
1
2
3
4
5
6
7
8
9
10
11
12
double picon (double data [][3], int l){

	double num;
	double ans = 1;
	int x;
	for (x=0 ; x<l ; ++x){
		num = 1 / (data[x][2] * sqrt(2*3.14159265359));
		ans = ans * num ;
	}
return (ans);

}


hope that was useful.
Rechard3 wrote:
when you define an array, you're actually defining a pointer to the first element in it, and allocating memory for it in compile time.
pointer -> values

This is not true. Arrays are not pointers. The memory is usually not allocated at compile time, but at runtime, when the function where the array is defined is called. If the memory was allocated at compile time you would get problems if you define an array in a recursive function because each function call should have it's own array.

Rechard3 wrote:
when you define a 2D array, you're actually defining a pointer to a 1D array of pointers, each one points to a 1D array of values.
pointer -> pointers -> values
this a 2 level pointer

A 2D array is an array of arrays.

Rechard3 wrote:
the compiler tries to convert data to the correct 3 level pointer, problem is.... C++ cannot convert double** to double***

If data was a double** it would be possible to get a double*** by using operator& i.e. &data but it is not possible because the type of data in main is double(*)[3] (pointer to array of 3 doubles) so using dereference operator would give you a double(**)[3] (pointer to pointer to array of 3 doubles).
Last edited on
so Peter87, i wasn't trying to provide some misleading info, i wanted to give an easy to understand demonstration about the nature of arrays for beginners.

i mentioned compile time just to point out that he cannot change the size in runtime.

i really appreciate your accurate correction, but i don't think a beginner would understand such deep principles.
i'm not saying i'm an expert, i'm a beginner after all.

edit:
2D array isn't an array of pointers, but you can deal with it as if it were, consider this:
1
2
3
4
5
6
7
8
9
10
#include<iostream>
using namespace std;

void main()
{
	int a[2][2] = { {11,12},{21,22} };
	for(int i=0;i<2;i++)
		for(int j=0;j<2;j++)
			cout<< * ( a[i] + j ) <<endl;
}


i'm not questioning your accuracy, i'm giving my experience.
Last edited on
The array's variable name itself when correctly dereferenced will return an address, which is the address of the first element in the array by default (index 0), but if the "[]" operator is used it will return the address of the element that is specified by the []. For the idea of the array being a pointer, it points to the first element in the array for purposes of keeping track of the data in memory. And it can be dereferenced with the [] operator to return the value at that offset location. Looking more into how arrays operate a bit "under the hood" may help understand how arrays and pointers relate to each other...and why saying an array is a pointer isn't exactly true, but kind of is.

It's then easy to find any location in the array via an index, which actually represents an offset to the first element's memory address. When you traverse an array it finds the position of the next element by modifying the address of the current data element. Since each element is adjacent in memory, the address can be adjusted by adding the size of the array's data type in memory to the current element's address to attain the next element's address. The idea of the index is perfect here, because we're always taught when first learning about arrays that the index is the number of elements away from the first one. i.e. The number of times that the address has to be incremented from the first element's address to get to the one of interest. That is why indexing works.

For example, an array is initialized as data type int with 3 elements. An integer takes up 4 bytes of space in memory. Therefore an array of 3 ints take up a total of 12 bytes adjacent to each other (4 bytes per int). Say the first element, at index 0, is at memory location 1000 for the sake of simplicity. Each element's address that follows is 4 bytes away consecutively. This means that element 2 at index 1 is at address 1004. And it follows that the third element, at index 2, is at address 1008. Index = 1, the original address is modified by sizeof(int)*1, which is 4*1.

This idea may have been what you were referencing, but it is a different idea than strictly declaring a pointer like declaring int* or char*. It's almost like a pointer with a catch, or a special pointer, but pretty much only functions as one for the sake of indexing its elements. I read somewhere that you can pass an array into a function that takes a pointer and it works, but I've never tried it.
Last edited on
all of your input are welcome with me guys, they are really accurate.
i never said that arrays are EXACTLY the same as pointers.
all i'm saying is, i deal with an array in pointer arithmetic:
it's faster.
it shows the true nature of an array.

i never pass an array to a function, i pass a pointer.
maybe some will start telling me that pointers are bad/evil/hard/bugsource...etc.

well...they can be a bug source, but they are incredibly efficient if you implement them really carefully, i just love using pointers and pointer arithmetic.
now maybe we got off topic on this one, didn't we !

Edit: and Peter87, just by looking at how many posts you've been through i can tell you're a greatly experienced programmer, please don't be bothered by a beginner like me.
Last edited on
ENIGMAx wrote:
The array's variable name itself when correctly dereferenced will return an address, which is the address of the first element in the array by default (index 0), but if the "[]" operator is used it will return the address of the element that is specified by the [].


You might want to look up dereference with respect to pointers. This is pretty much all wrong.


ENIGMAx wrote:
When you traverse an array it finds the position of the next element by modifying the address of the current data element.

It moves the current data element to a different address when you traverse an array?


ENIGMAx wrote:
For example, an array is initialized as data type int with 3 elements.

Should probably look up initialize when you look up dereference.


I would suggest ignoring ENIGMAx's explanation unless you really want to confuse yourself further.
ENIGMAx wrote:
When you traverse an array it finds the position of the next element by modifying the address of the current data element.

It moves the current data element to a different address when you traverse an array?


No, I said
it finds the position of the next element by modifying the address of the current data element
IN ORDER to calculate that next element's address...(which was obviously implied given the context)


In computer programming, initialization is the assignment of an initial value for a data object or variable. -Wikipedia
I think that's a good enough definition for someone to get the point that an array is being created in a program.

The dereference operator or indirection operator, denoted by "*" (i.e. an asterisk), is a unary operator found in C-like languages that include pointer variables. It operates on a pointer variable, and returns an l-value equivalent to the value at the pointer address. This is called "dereferencing" the pointer.
Yep, I'm wrong there. Dereference grabs the value that the pointer is pointing to. But hey, none of us are perfect. Thanks for the clarification though (all seriousness) sometimes people mince words and it can hinder someone that is just learning programming or lingo.

Peace.
Last edited on
You defined data as a pointer to an array of three elements.

double (*data)[3]= new double [15][3];

And you are going to process it in a function. So you should define the parameter of the function the same way as data was defined. So the function declaration will look the following way

double picon (double (* data)[3], int l);

As you see types of the parameter and of the argument coinside.

At present you defined the parameter as

double* data [][3]

It is an incomplete type of a two dimensional array elements of which has type double *.

As you see double and double * are two different types.

You could define the parameter as

double data [][3]

Take into account that the following function declarations are equivalent

double picon (double data [15][3], int l);

double picon (double data [][3], int l);

double picon (double (* data)[3], int l);


Topic archived. No new replies allowed.