Hey guys, I'm having issues returning my array at the end of my code, when I do the array is not the same as it was before being returned (which can be seen by the printout). I also get a warning from my compiler: "warning: address of local variable 'garray' returned"

Can anyone help me out? I don't understand pointers in C++ (my first language was IDL which basically writes itself), I've tried reading up on them but I'm lost...

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>;
using namespace std;

double* loadfile (string path) 
//int main()
{

	//cout << "\nEnter the path for the file:\n";
	string gnumber;
	cin >> path;
	int linenumber = 1,index,gcounter=0;
	double garray[96],temparray[192][79],firstaveragearray[96][79];
	
	string line;
	ifstream myfile ( "/users/tc/desktop/scott-for-tyler/cfun_m0/cf2_octn.all.new" );//path.c_str() );
	if (myfile.is_open())
	{
		while (! myfile.eof())
		{
			
			getline (myfile,line);
			if ((linenumber != 30416) && (linenumber != 30417)) {
				
				if ((linenumber)%(385) > 1) {
					if ((linenumber)%(385) < 98) {
						index = line.find_last_of(" ");
						gnumber = line.substr(index,23);
						temparray[gcounter%192][gcounter/192]=atof(gnumber.c_str());
						gcounter = gcounter ++;
						
					}
				}
				
				if ((linenumber)%(385) > 193) {
					if ((linenumber)%(385) < 290) {
						index = line.find_last_of(" ");
						gnumber = line.substr(index,23);
						temparray[gcounter%192][gcounter/192]=atof(gnumber.c_str());
						gcounter = gcounter++;
						
					}
				}
			}
			
			linenumber = linenumber ++;
		}
		
		myfile.close();
		

		
		//for (int n = 0; n != 79; n++) {cout << "\n" << setprecision(20)<< temparray[79][n];}
		//cout << "\n\n\n\n\n\n\n\n\n\n";
		
		
		
		//now we average two terms, reducing each vector to length 48*2=96
		
		for (int m = 0; m != 79; m++)
		{
			
			for (int n = 0; n != 96; n++)
			{ firstaveragearray[n][m]=(temparray[n][m]+temparray[n+96][m])/2; }
			
		}
		
		//now we take and average components over all 79 vectors.
		
		for (int n = 0; n != 96; n++)
		{
			for (int m = 0; m != 79; m++) {	garray[n] = garray[n] + firstaveragearray[n][m]; }
		}
		
		for (int n = 0; n != 96; n++) { garray[n] = garray[n]/79; }
		
		for (int n = 0; n != 96; n++) { cout << "\n" << garray[n]; }
		
		cout << "\n\n\n\n\n\n\n\n\n\n";
		
		
		return garray; 
	}
	
	else cout << "could not open file";
	
	return 0;
}

int main ()
{

	double* zerofield = loadfile("asdk");
	
	for (int n = 0; n != 96; n++) { cout << "\n" << zerofield[n]; }

	
	return 0;
}

When you look at my output you can see the discrepancies start at the 50th element of the vector...

0.614641
0.0115048
0.000518967
4.35006e-05
7.68439e-06
2.15642e-06
7.77537e-07
3.1264e-07
1.35536e-07
6.09996e-08
2.84649e-08
1.31502e-08
6.04528e-09
2.77905e-09
1.30092e-09
6.2143e-10
2.79105e-10
1.27637e-10
5.48915e-11
1.88296e-11
4.61608e-12
-3.16146e-13
-2.98603e-12
-2.91328e-12
-2.1937e-12
-1.26807e-12
-1.53015e-13
4.11316e-13
-2.99663e-13
1.14983e-12
7.12885e-13
-4.54224e-12
-5.76504e-12
-1.33306e-11
1.02794e-11
6.60723e-11
1.25979e-10
1.90792e-10
-5.29945e-11
-1.51258e-09
-5.455e-09
-2.20862e-08
-8.84432e-08
-3.58778e-07
-1.76736e-06
-1.1897e-05
-0.000126254
-0.00221094
0.61537
0.0115372
0.000522238
4.38911e-05
7.78644e-06
2.17494e-06
7.75285e-07
3.0602e-07
1.28791e-07
5.70419e-08
2.64364e-08
1.2334e-08
5.8283e-09
2.73495e-09
1.29892e-09
6.18274e-10
2.98773e-10
1.4751e-10
7.73197e-11
3.89099e-11
2.10247e-11
1.00825e-11
1.82238e-12
-1.30814e-12
-1.62036e-12
-1.7026e-12
-6.53891e-13
-4.97935e-13
-3.06673e-13
-3.10042e-12
-4.20526e-12
-8.04596e-12
-9.27229e-12
-1.1649e-11
3.83844e-12
-1.29512e-11
-1.75329e-11
-1.3256e-10
-4.72506e-10
-2.39797e-09
-9.52376e-09
-3.08168e-08
-1.06527e-07
-4.00965e-07
-1.91054e-06
-1.22746e-05
-0.000128517
-0.00220908




0.614641
0.0115048
0.000518967
4.35006e-05
7.68439e-06
2.15642e-06
7.77537e-07
3.1264e-07
1.35536e-07
6.09996e-08
2.84649e-08
1.31502e-08
6.04528e-09
2.77905e-09
1.30092e-09
6.2143e-10
2.79105e-10
1.27637e-10
5.48915e-11
1.88296e-11
4.61608e-12
-3.16146e-13
-2.98603e-12
-2.91328e-12
-2.1937e-12
-1.26807e-12
-1.53015e-13
4.11316e-13
-2.99663e-13
1.14983e-12
7.12885e-13
-4.54224e-12
-5.76504e-12
-1.33306e-11
1.02794e-11
6.60723e-11
1.25979e-10
1.90792e-10
-5.29945e-11
-1.51258e-09
-5.455e-09
-2.20862e-08
-8.84432e-08
-3.58778e-07
-1.76736e-06
-1.1897e-05
-0.000126254
-0.00221094
0.61537
0.011536
0.000522238
4.38911e-05
7.78644e-06
2.17494e-06
7.75285e-07
3.0602e-07
1.28791e-07
5.70419e-08
2.64364e-08
1.2334e-08
5.8283e-09
2.73495e-09
3.71349e-314
3.3241e-314
9.81494e-314
1.22015e-313
1.40589e-313
3.89099e-11
2.10247e-11
1.00825e-11
1.82238e-12
-1.30814e-12
-1.30814e-12
-1.7026e-12
-6.53891e-13
-1.99701
0
-3.10028e-12
-1.99752
2.122e-314
nan
7.8804e+115
3.83844e-12
-5.53404e-227
9.70813e-313
-5.53595e-227
-3.41298e-154
-1.99754
-9.52376e-09
1.26626e-64
0
0
0
0
0
0

Alright, well I figured out this solution while I was continuing working on it. Could someone brief over it and tell me if there's any memory issues?

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>;
using namespace std;

double * loadfile (string path) 
//int main()
{

	//cout << "\nEnter the path for the file:\n";
	string gnumber;
	cin >> path;
	int linenumber = 1,index,gcounter=0;
	double garray[96],temparray[192][79],firstaveragearray[96][79];
	
	string line;
	ifstream myfile ( "/users/tc/desktop/scott-for-tyler/cfun_m0/cf2_octn.all.new" );//path.c_str() );
	if (myfile.is_open())
	{
		while (! myfile.eof())
		{
			
			getline (myfile,line);
			if ((linenumber != 30416) && (linenumber != 30417)) {
				
				if ((linenumber)%(385) > 1) {
					if ((linenumber)%(385) < 98) {
						index = line.find_last_of(" ");
						gnumber = line.substr(index,23);
						temparray[gcounter%192][gcounter/192]=atof(gnumber.c_str());
						gcounter = gcounter ++;
						
					}
				}
				
				if ((linenumber)%(385) > 193) {
					if ((linenumber)%(385) < 290) {
						index = line.find_last_of(" ");
						gnumber = line.substr(index,23);
						temparray[gcounter%192][gcounter/192]=atof(gnumber.c_str());
						gcounter = gcounter++;
						
					}
				}
			}
			
			linenumber = linenumber ++;
		}
		
		myfile.close();
		

		
		//for (int n = 0; n != 79; n++) {cout << "\n" << setprecision(20)<< temparray[79][n];}
		//cout << "\n\n\n\n\n\n\n\n\n\n";
		
		
		
		//now we average two terms, reducing each vector to length 48*2=96
		
		for (int m = 0; m != 79; m++)
		{
			
			for (int n = 0; n != 96; n++)
			{ firstaveragearray[n][m]=(temparray[n][m]+temparray[n+96][m])/2; }
			
		}
		
		//now we take and average components over all 79 vectors.
		
		for (int n = 0; n != 96; n++)
		{
			for (int m = 0; m != 79; m++) {	garray[n] = garray[n] + firstaveragearray[n][m]; }
		}
		
		for (int n = 0; n != 96; n++) { garray[n] = garray[n]/79; }
		
		for (int n = 0; n != 96; n++) { cout << "\n" << garray[n]; }
		
		cout << "\n\n\n\n\n\n\n\n\n\n";
		
		double * address = & garray[0];
		
		return address; 
	}
	
	else cout << "could not open file";
	
	return 0;
}

int main ()
{

	double * zerofieldaddress = loadfile("asdk");
	double zerofield[96];
	for (int n = 0; n != 96; n++)
	{
		zerofield[n] = *(zerofieldaddress + n);
	}
	
	for (int n = 0; n != 96; n++) { cout << "\n" << zerofield[n]; }

	
	return 0;
}

> When you look at my output you can see the discrepancies start at the 50th element of the vector...
Yes, the code is still broken. You're returning a pointer to a local variable.
The result is that some of your data is trashed when that bit of the stack gets re-used for something else.

As this is C++, consider the following function prototype. void loadfile ( string filename, std::vector<double> &results );

Alright, well I figured out this solution while I was continuing working on it. Could someone brief over it and tell me if there's any memory issues?

double* loadfile (string path){
	double garray[96],temparray[192][79],firstaveragearray[96][79];
	...	
		double * address = & garray[0];
		return address; 
	
	else cout << "could not open file";
	
	return 0;
}

You are on a suicide mission with this code! However, it can be easily fixed. First, the the previous poster noted, you are allocating the array locally (to the loadfile function) and then returning a pointer to that locally allocated array. This is very, very bad. When you allocate a local array like
int localArr[10];
Inside of a function, the program reserves that memory space on the program stack. This memory is reserved only as long as the program is in that function. So, when you return a pointer to that memory, the pointer is invalid. Once the function has returned, the program can use the memory space that used to be restricted for local variabes for anything. The only reason you were getting back your values was because the program hadn't used that memory space yet, so the bits were unchanged. If you want to preserve data you need to use some sort of dynamic memory allocation like this:

double* someFunction(){
   double* someArray = new double[5];
   someArray[4] = 7;
   return someArray;
}
int main(){
   double *someArray = someFunction();
   cout << someArray[4] << endl;
   delete [] someArray;
   return 0;
}

Here, the new and delete keywords are the big thing. The new keyword tells the program to allocate some memory on the heap. This is memory that will remain protected for the lifetime of the program. The program cannot use this memory again until the delete keyword tells the program that this memory is available again.

However, it isn't very good practice to allocate memory in a called function and then have to de-allocate in the calling function. Here's a better way to do this:

void someFunction( double* someArray ){
   someArray[4] = 7;
}

int main(){
   double *someArray = new double[5];
   someFunction( someArray );
   cout << someArray[4] << endl;
   delete [] someArray;
   return 0;
}

This way, it's easier to keep track of all your news and deletes. A good rule of thumb is that memory should be deallocated in the same scope that it was allocated in. This way, you can make sure that you free up any of the memory that the function used.

Memory management is a crucial concept for C and C++. You should probably read up on how this all works from a more extensive source than this forum (like a text book). The key is, you must be very careful with how you manage your memory, or you will get buried in segmentation faults and memory corruptions.

Good luck!

This article has been dead for over six months. Start a new discussion instead.