Click here to Skip to main content
15,896,063 members
Please Sign up or sign in to vote.
3.33/5 (3 votes)
See more:
Can any body guide me what is wrong with my code
void main()
{
	
	double **data;
	data=new double*[1];
	data[0]=new double[3];
	int rows=reading(2,data);
	for(int i=0; i<rows; i++)
	{
		for(int j=0; j<3; j++)
		{
			cout<<data[i][j]<<"\t";
		}
		cout<<"\n";
	}
	cout << rows<<endl;
	cout<<data[0][2]<<"\n";
}
int reading(int r,double **data)
{
	if (r%2!=0)
	{
		r++;
	}
	int rows=r;
	delete[] data;
	data=new double*[rows];
	for(int k=0; k<rows; k++)
	{
		data[k]=new double[3];
	}
	for(int i=0; i<rows; i++)
	{
		for(int j=0; j<3; j++)
		{
			data[i][j]=i+j;
		}
	}
	return rows;
}


I want to do is to allocate memory to 2D dynamic array using a function, but function is called in function everything works fine, but when it return rows and back to main, the **data remain its initial address instead of address allocated by assigning new memory space in function. As i passed data as a double pointer in function it should get changed when changes are made in function.
Posted

The passing values (or their pointers) are placed on the stack,
so they are "visible" in the receiving functions only :) :
void f(int iPar)
{
  iPar++; // the local only increment
}

void d(int* piPra)
{
  if (piPar) {
    (*piPar)++; // outgoing increment
  }
}

void test()
{
  int i(2);
  f(i);
  // i == 2
  d(&i);
  // i == 3;
}


The operations new or delete will also modify the passed pointers:
- local only, when the pointers passed as value
- outgoing, when the pointers passed by their addresses (pointer to pointer)

Now you will probably understand what you need ? :)

Of course, it will be a modified function:
int reading(int iRows, double*** pppData)
{
...
}
 
Share this answer
 
Comments
[no name] 2-Mar-11 15:30pm    
Actually you're right and it was lucky that my compiler managed to run the code correctly anyway :)
Removed my answer.
Shirani 3-Mar-11 2:56am    
i tried this got this error :(

1>visual studio 2005\projects\t\t\t1.cpp(34) : error C2440: '=' : cannot convert from 'double **' to 'double ***'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>visual studio 2005\projects\t\t\t1.cpp(37) : error C2440: '=' : cannot convert from 'double *' to 'double **'
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>visual studio 2005\projects\t\t\t1.cpp(43) : error C2440: '=' : cannot convert from 'int' to 'double *'
1> Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
1>Build log was saved at "file://Visual Studio 2005\Projects\t\t\Debug\BuildLog.htm"
1>t - 3 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
if you want to change ** data in function , you should pass a ***data to it , use &data in main function.(Sorry ,my English is not very good )
 
Share this answer
 
v2
The top level value is passed into a function by value. That is the value is copied.

Consider this a crash course in basic pointers and pass by value.
You should really read something about it, although I couldn't recommend a good book as I just learnt things by playing around to see what happened.

Consider a more simple example:
char *szStr = "hello";

The variable szStr now contains a value that points to the memory where <code>"hello"</code> is stored.
For this example, we will say that this memory location is <code>0x1000</code>.
This means that at memory location <code>0x1000</code> - <code>0x1006</code> we have the characters 'h', 'e', 'l', 'l', 'o', '\0'


//Now call a function passing in the pointer szStr
PrintStr(szStr);

void PrintStr(char *szPrint) {
	++szPrint; //Increase the value of the pointer, so that we start printing from the 2nd char
	//This does not change the value of szStr, which was what was passed into the function
	//szPrint is now 0x1001, which points to "ello"
	//szStr is still 0x1000, which points to "hello"
	puts(szPrint);
	szPrint[0] = 'E';
	//szPrint is now 0x1001, which points to "Ello"
	//szStr is still 0x1000, which points to "hEllo"
	//we can change the data been pointed to just fine in both copies
}

What is actually happening here is that we are copying the value of the pointer szStr (which is 0x1000) onto the stack for the function PrintStr.
Because we have passed in a copy, any changes made to this copy of the pointer value wont be made to the value of szStr.
However, both szStr and the copy (szPrint parameter) contain 0x1000, and hence reference the same memory location.
This means that any changes made to the characters in szPrint will also be changed in szStr

So, referring back to my first sentence, the top level here is the memory location that is stored in szStr and szPrint (0x1000).

No to your actual problem.
As has been previously suggested, you can make a tripple pointer and pass that in:
void main(){
	double **data;
	//initialise as normal
	int rows=reading(2,&data);
	//rest as normal
}
int reading(int r,double ***data) {
	if (r%2!=0) {
		r++;
	}
	int rows=r;
	delete[] *data;
	*data=new double*[rows];
	for(int k=0; k<rows; k++) {
		(*data)[k]=new double[3];
	}
	for(int i=0; i<rows; i++) {
		for(int j=0; j<3; j++) {
			(*data)[i][j]=i+j;
		}
	}
	return rows;
}


Or, since you indicated you are using C++, you can use pass by reference, which uses some clever tricks to not copy the value when passing it into the function, and also means that you dont need to worry about doing crazy things like (*data)[i][j]=

This would look like:
void main() {
	//This code is unchanged. Convenience is nice.
}
int reading(int r,double &**data) { //Notice the &
	//This code is unchanged too.
	//Much simpler and prettier.
}
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900