int ** a;
int limit = 0;
//...
if (choice == 1)
{
a = newint * [limit];
int i;
for (i = 0; i < limit; i++) a[i] = newint [limit];
//...
}
elseif (choice == 2)
{
readData(a, limit);
Display(a, limit);
//...
}
//...
void readData(int ** matric, int dimension)
{
//...
for (int r = 0; r < dimension; r++)// row loop
{
for (int c = 0; c < dimension; c++) // column loop
{
inFile >> matrix[r][c]; // read data into matrix
// ... This line causes the program to crash
}
}
//...
}
Your problem is that you allocated sufficient space for your matrix in the if clause, but no in the other clauses, so i choice is 2, a would be an uninitialized pointer, it doesn't point to a block in memory. Moreover, limit is still 0.
Next time, please try to use the debugger, you can pinpoint the problem or at least narrow the code block you feel suspicious about. Then, you can post it and people won't get afraid at the sight of a huge piece of code.
how i readData() from this TXT file and store back to my dynamic array so that my boolean function can work? no idea about it.. a lot senior trying to help..
I was thinking about this - note that I haven't got time to test the code right now, but I think this is the problem:
You store an array like this:
1 2 3 4
3
8 1 6
3 5 7
4 9 2
Where the first number is the dimension.
So instead of using the dimension that was passed to the readData function, you should use that first number as your dimension.
In order to do so, change:
inFile.ignore(5,'\n'); //line 118
To:
inFile >> dimension;
However, you should be careful using pointers in this way, because it may result in memory leaks.
It would be safer to use a std::vector matrix (you're only iterating the matrix front to back every time anyway).
I suggest the following realization of function readData. The file name is passed as an argument to the function. So it has to be entered in the main. Also the function accepts pointer to the matrix which in the main has to be defined as
int **a = 0;
If the fiile was successfully opened when read in data otherwise return 0 as dimension of the square.
#include <iostream>
int readData( int ***matrix )
{
int dimension = 5;
*matrix = newint *[dimension];
for ( int r = 0; r < dimension; r++ )
{
( *matrix )[r] = newint[dimension];
}
for ( int r = 0; r < dimension; r++ )// row loop
{
for ( int c = 0; c < dimension; c++ ) // column loop
{
( *matrix )[r][c] = r * dimension + c; // read data into matrix
}
}
return ( dimension );
}
int main()
{
int **a = 0;
int d = readData( &a );
for ( int i = 0; i < d; i++ )
{
for ( int j = 0; j < d; j++ )
{
std::cout << a[i][j] << ' ';
}
std::cout << std::endl;
}
for ( int i = 0; i < d; i++ ) delete [] a[i];
delete [] a;
return 0;
}
So the only you need to return to the original realization is to add std::ifstream
and read data from the stream instead of initialization the array as in this example.
You can also to write a separate function that will delete the pointer before reading a next file and before exiting the program.
1 2 3 4 5 6 7 8 9
void clearMatrix( int ***matrix, int dimension )
{
if ( *matrix )
{
for ( int i = 0; i < dimension; i++ ) delete [] ( *matrix )[i];
delete [] *matrix;
*matrix = 0;
}
}
In this case the body of the main of the previous test program will look the following way
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
int main()
{
int **a = 0;
int d = readData( &a );
for ( int i = 0; i < d; i++ )
{
for ( int j = 0; j < d; j++ )
{
std::cout << a[i][j] << ' ';
}
std::cout << std::endl;
}
clearMatrix( &a, d );
return 0;
}
Now all is ready to update your original program taking as a base this test program.
For example to test displaying the files you can write
thanks for your help and currently my code are working fine..
it can read the file and I can use the function to compare whether is magic square or not already =) . it too hard for me.. by the way..
can you give me some explanation beside the code? for
why you use
*** int matrix
and which line are you using that READ from the text file and can save back to the 2d dimension array?
#include <iostream>
void f( int x ) { x = 20; }
int main()
{
int x = 10;
std::cout << "Before f( x ) x = " << x << std::endl;
f( x );
std::cout << "Before f( x ) x = " << x << std::endl;
}
In the example value of x was not changed after calling f.
Now consider a lightly updated example.
1 2 3 4 5 6 7 8 9 10 11 12
#include <iostream>
void f( int *x ) { *x = 20; }
int main()
{
int x = 10;
std::cout << "Before f( x ) x = " << x << std::endl;
f( &x );
std::cout << "Before f( x ) x = " << x << std::endl;
}
In this example the value of x was changed after calling f.
The same is valid for the declaration
int **a;
Inside readData the value of 'a' must be changed because we always allocate the memory anew every time the function is called. So 'a' is passed to function by reference that is by using pointer. If 'a' itself would be passed to the function then a local copy of 'a' would be created inside the function body and after exiting the function this local copy would be destroyed. So the original value of 'a' would not be changed. In general when a pointer to object is passed a local copy of it is created in a called function. But we change not the pointer iteslf but the object that is referenced by the pointer. After exiting the function local copy of the pointer is destroyed however the object pointer by the pointer will keep its new value because we directly assign to it a new value not to its copy. One more consider the first example with int x.