Help with pointers and arrays, please!

Pages: 12
Feb 5, 2013 at 7:42pm
Hi all.

I'm learning c++ by myself, and right now I'm working in a basic problem of arrays. I want to create a code that multiplies matrices. I wrote the code already and it works, but I wanna do it using functions and pointers, but then, everything is messed up. This is the code that I have so far, here is only the part where I ask the user for the dimensions and entries of the matrices, no multiplication is done yet. I have a couple of errors and I've been reading the references that I am following and asked a couple of fellas but no help. If anyone can give me some help, I appreciate it. Thanks!

***********************************************************
#include<iostream>
#include<cmath>
void intro()
{
using namespace std;
cout << "*****************************************************" << endl;
cout << "Program to calculate the product of two matrices C=AB" << endl;
cout << "*****************************************************" << endl;
}
void get_A(double**& A, int& rowsA, int& colsA)
{
using namespace std;
//double** A;
cout << "********************************" << endl;
cout << "Enter the dimensions of matrix A" << endl;
cout << "********************************" << endl;
cout << "Number of rows: ";
cin >> rowsA;
cout << "Number of columns: ";
cin >> colsA;
cout << "********************************" << endl;
A = new double [rowsA][colsA];

for(int i=0; i<rowsA; i++)
{
for(int j=0; j<colsA; j++)
{
cout << "A[" << i << "," << j << "] = ";
cin >> A[i][j];
}
}
}
void get_B(double**& B, int& rowsB, int& colsB)
{
using namespace std;
// double** B;
cout << "********************************" << endl;
cout << "Enter the dimensions of matrix B" << endl;
cout << "********************************" << endl;
cout << "Number of rows: ";
cin >> rowsB;
cout << "Number of columns: ";
cin >> colsB;
cout << "********************************" << endl;
B = new double [rowsB][colsB];

for(int i=0; i<rowsB; i++)
{
for(int j=0; j<colsB; j++)
{
cout << "B[" << i << "," << j << "] = ";
cin >> B[i][j];
}
}
}
//void FreeMatrix_A(double** A, int rowsA, int colsA)
//{
//for(int i=0; i<rowsA; i++)
// {
// for(int j=0; j<colsA; j++)
// {
// delete[] A[i][j];
// }
// }
//delete[] A;
//}
//void FreeMatrix_B(double** B, int rowsB, int colsB)
//{
//for(int i=0; i<rowsB; i++)
// {
// for(int j=0; j<colsB; j++)
// {
// delete[] B[i][j];
// }
// }
//delete[] B;
//}
int main(int argc, char* argv[])
{
//using namespace std;

double** A;
double** B;
int rowsA, colsA, rowsB, colsB;

intro();
get_A(A, rowsA, colsA);
get_B(B, rowsB, colsB);
delete [] A;
delete [] B;
return 0;
}
Feb 5, 2013 at 7:45pm
Can you copy and paste the error messages you are getting?

Also, for code, you can past code [code]between code tags[/code] to get formatting like this. It makes it easier to read than just the plain text.
Last edited on Feb 5, 2013 at 7:46pm
Feb 5, 2013 at 8:14pm
These are the erros that I am getting :

$ matrix_product_2.cpp: In function ‘void get_A(double**&, int&, int&)’:
$ matrix_product_2.cpp:22:26: error: ‘colsA’ cannot appear in a constant-expression
$ matrix_product_2.cpp: In function ‘void get_B(double**&, int&, int&)’:
$ matrix_product_2.cpp:45:26: error: ‘colsB’ cannot appear in a constant-expression

I'm sorry, I feel fool today, but I can not put my code into tags as you told me :( [/try]

Feb 5, 2013 at 8:17pm
A = new double [rowsA][colsA];

B = new double [rowsB][colsB];

C++ doesn't work this way (though Java does). You have to make it an array of pointers and then go through each and initialize it to an array (think of it an an 'array of arrays').
Last edited on Feb 5, 2013 at 8:17pm
Feb 5, 2013 at 8:25pm
Thank you, I will try to work on it.
Feb 5, 2013 at 9:37pm
Hey, I was working on it, I did something that fixed errors but now when I run the code I can enter the dimensions of the matrix A and then my compiler shows me this:
Segmentation fault (core dumped) 
. Here goes the code (Thanks for the help!):

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include<iostream>
#include<cmath>
void intro()
{
 using namespace std;
  cout << "*****************************************************" << endl;
  cout << "Program to calculate the product of two matrices C=AB" << endl;
  cout << "*****************************************************" << endl;
}
void get_A(double**& A, int& rowsA, int& colsA)
{
  using namespace std;  
   //double** A;
  cout << "********************************" << endl;
  cout << "Enter the dimensions of matrix A" << endl;
  cout << "********************************" << endl;
  cout << "Number of rows: ";
  cin >> rowsA;
  cout << "Number of columns: ";[
  cin >> colsA;
  cout << "********************************" << endl;
 
  for(int i=0; i<rowsA; i++)
    {
      A[i] = new double [colsA];
    }
  for(int i=0; i<rowsA; i++)
    {
      for(int j=0; j<colsA; j++)
	{
	  A[i][j]=0.0;
	  cout << "A[" << i << "," << j << "] = ";
	  cin >> A[i][j];
	}
    }
}
void get_B(double**& B, int& rowsB, int& colsB)
{
  using namespace std;
  //  double** B
  cout << "********************************" << endl;
  cout << "Enter the dimensions of matrix B" << endl;
  cout << "********************************" << endl;
  cout << "Number of rows: ";
  cin >> rowsB;
  cout << "Number of columns: ";
  cin >> colsB;
  cout << "********************************" << endl;
  for(int i=0; i<rowsB; i++)
    { 
      B[i] = new double [colsB];
    }
  for(int i=0; i<rowsB; i++)
    {
      for(int j=0; j<colsB; j++)
	{
	  B[i][j]=0.0;
	  cout << "B[" << i << "," << j << "] = ";
	  cin >> B[i][j]; 
	}
    }
}
void Multiply(double** A, double** B, double** C, int& rowsA, int& colsA, int& colsB)
{
  using namespace std;
  for(int i=0; i<rowsA; i++)
    {
      C[i] = new double [colsB];
    }
  for(int i=0; i<rowsA; i++)
    {
      for(int j=0; j<colsA; j++)
	{
	  for(int k=0; k<colsA; k++)
	    {
	      C[i][j]=0.0;
	      C[i][j] = A[i][k]*B[k][k];
	    }
	  cout << "C[" << i << "," << j << "] = " << C[i][j] << endl;
	}
    }
}
int main(int argc, char* argv[])
{
  //using namespace std;
  double** A;
  double** B;
  int rowsA, colsA, rowsB, colsB;
  intro();
  get_A(A, rowsA, colsA);
  get_B(B, rowsB, colsB);
  delete [] A;
  delete [] B;
  return 0;
}


Feb 5, 2013 at 10:26pm
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void get_A(double**& A, int& rowsA, int& colsA)
{
  using namespace std;  
   //double** A;
  cout << "********************************" << endl;
  cout << "Enter the dimensions of matrix A" << endl;
  cout << "********************************" << endl;
  cout << "Number of rows: ";
  cin >> rowsA;
  cout << "Number of columns: ";[
  cin >> colsA;
  cout << "********************************" << endl;
 
  for(int i=0; i<rowsA; i++)
    {
      A[i] = new double [colsA];
    }
You have to create A before you can create each A[i], and same for B. It should be a simple fix.
92
93
  delete [] A;
  delete [] B;
You have to go through and delete each sub-array before you can delete these outer arrays, otherwise you have a memory leak.
Feb 5, 2013 at 11:36pm
I fixed functions get_A and get_B, the problem now is with the Multiply function to get C. When I finish typing entries of B, I get the same error
Segmentation fault (core dumped)
: I'm lost, help please

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
void Multiply(double**A, double** B, int& rowsA, int& colsA)
{
  using namespace std;
  double** C;
  //rowsA;
  //colsC = colsB;
  C = new double* [rowsA];
  //for(int i=0; i<rowsC; i++)
  //{
  //  C[i] = new double [colsC];
  //}
  for(int i=0; i<rowsA; i++)
    {
      for(int j=0; j<colsA; j++)
	{
	  for(int k=0; k<colsA; k++)
	    {
	      C[i][j]=0.0;
	      C[i][j] += A[i][k]*B[k][j];
	    }
	  cout << "C[" << i << "," << j << "] = " << C[i][j] << endl;	
	}
    }
}
void FreeMatrix_A( int rowsA, double** A)
{
  for(int i=0; i<rowsA; i++)
    {
      delete[] A[i];
    }
  delete A;
}
void FreeMatrix_B(int rowsB, double** B)
{
  for(int i=0; i<rowsB; i++)
    {
      delete[] B[i];
    }
  delete B;
}
void FreeMatrix_C(int rowsA, double** C)
{
  for(int i=0; i<rowsA; i++)
    {
      delete[] C[i];
    }
  delete C;
}
int main(int argc, char* argv[])
{
  //using namespace std;
  double** A;
  double** B;
  double** C;
  int rowsA, colsA, rowsB, colsB;
  
  intro();
  get_A(rowsA, colsA);
  get_B(rowsB, colsB);
  Multiply(A, B, rowsA, colsA);
  FreeMatrix_A(rowsA, A);
  FreeMatrix_B(rowsB, B);
  FreeMatrix_C(rowsA, C);
  
  return 0;
}
Feb 6, 2013 at 1:47am
Of course you get a segfault when you comment lines 8-11. ;)
Feb 6, 2013 at 5:07pm
I made the comments because I thought that was the problem, even without that, the program is not running. Thanks for your help.
Feb 6, 2013 at 5:11pm
What do you mean by "the program is not running"? What happens?
Feb 6, 2013 at 5:17pm
I can enter the coefficients of A and B with no problem, and when I'm done it says again: segmentation fault (core dumped). I think the problem is with the function multiply, when it makes the product to get the elements of C, but I have no idea what else to do, and I don't have professors here to ask :(.
Feb 6, 2013 at 5:18pm
Is that when lines 8-11 are commented out? What happens when they are not commented out? (They should not be commented out)
Feb 6, 2013 at 5:19pm
They are not commented now, and it says the same :(
Feb 6, 2013 at 5:24pm
So, you know that the problem is with the function for multiplying C. Look at the function.
41
42
43
44
45
46
47
48
void FreeMatrix_C(int rowsA, double** C)
{
  for(int i=0; i<rowsA; i++)
    {
      delete[] C[i];
    }
  delete C;
}
I think you copy and pasted because you forgot to change "rowsA" to "rowsC", though it doesn't matter because it is being passed as a parameter. So, look at what you are passing as the parameter:
61
62
63
  FreeMatrix_A(rowsA, A);
  FreeMatrix_B(rowsB, B);
  FreeMatrix_C(rowsA, C);
Should that not be "rowsC"?
Feb 6, 2013 at 5:31pm
Well, but I just realized that the number of rows of matrix C will be the same as matrix A, and even in the loop I put that condition, so for that reason I didn't see the reason to keep the variable rowsC and I just commented it, I don't know if that's right in C++. Now, if I write it as argument in FreeMatrix_C I will get the error of non defined variable.
Feb 6, 2013 at 5:35pm
LOL, I'm stupid. Sorry about that.

52
53
54
55
56
57
58
59
60
61
62
63
  double** A;
  double** B;
  double** C;
  int rowsA, colsA, rowsB, colsB;
  
  intro();
  get_A(rowsA, colsA);
  get_B(rowsB, colsB);
  Multiply(A, B, rowsA, colsA);
  FreeMatrix_A(rowsA, A);
  FreeMatrix_B(rowsB, B);
  FreeMatrix_C(rowsA, C);
Do you see? C never gets set to anything.
1
2
3
4
void Multiply(double**A, double** B, int& rowsA, int& colsA)
{
  using namespace std;
  double** C;
This is a completely different C, not the same one as in main.
Feb 6, 2013 at 11:16pm
Hey, no problem. I don't know, I can't see why the C that you say is different from the one in the main. I made some modifications but still I don't see the problem, here goes the code that I have :

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
 #include<iostream>
#include<cmath>
void intro()
{
  using namespace std;
  cout << "*****************************************************" << endl;
  cout << "Program to compute the product of two matrices C=AB" << endl;
  cout << "*****************************************************" << endl;
}
void get_A(int& rowsA, int& colsA)
{
  using namespace std;  
  cout << "********************************" << endl;
  cout << "Enter the dimensions of matrix A" << endl;
  cout << "********************************" << endl;
  cout << "Number of rows: ";
  cin >> rowsA;
  cout << "Number of columns: ";
  cin >> colsA;
  cout << "********************************" << endl;
  double** A;
  A = new double* [rowsA];
  for(int i=0; i<rowsA; i++)
    {
      A[i] = new double [colsA];
    }
  for(int i=0; i<rowsA; i++)
    {
      for(int j=0; j<colsA; j++)
	{
	  A[i][j]=0.0;
	  cout << "A[" << i << "," << j << "] = ";
	  cin >> A[i][j];
	}
    }
}
void get_B(int& rowsB, int& colsB)
{
  using namespace std;
  //  double** B;
  cout << "********************************" << endl;
  cout << "Enter the dimensions of matrix B" << endl;
  cout << "********************************" << endl;
  cout << "Number of rows: ";
  cin >> rowsB;
  cout << "Number of columns: ";
  cin >> colsB;
  cout << "********************************" << endl;
  double** B;
  B = new double* [rowsB];
  for(int i=0; i<rowsB; i++)
    { 
      B[i] = new double [colsB];
    }
  for(int i=0; i<rowsB; i++)
    {
      for(int j=0; j<colsB; j++)
	{
	  B[i][j]=0.0;
	  cout << "B[" << i << "," << j << "] = ";
	  cin >> B[i][j]; 
	}
    }
}
void get_C(double** A, double** B, int& rowsA, int& colsA, int& colsB)
{
  using namespace std;
  double** C;
  C = new double* [rowsA];
  for(int i=0; i<rowsA; i++)
    {
      C[i] = new double [colsB];
    }
  for(int i=0; i<rowsA; i++)
    {
      for(int j=0; j<colsA; j++)
	{
	  for(int k=0; k<colsA; k++)
	    {
	      C[i][j]=0.0;
	      C[i][j] += A[i][k]*B[k][j];
	    }
	  cout << "C[" << i << "," << j << "] = " << C[i][j] << endl;	
	}
    }
}
void FreeMatrix_A(int& rowsA, double** A)
{
  for(int i=0; i<rowsA; i++)
    {
      delete[] A[i];
    }
  delete A;
}
void FreeMatrix_B(int& rowsB, double** B)
{
  for(int i=0; i<rowsB; i++)
    {
      delete[] B[i];
    }
  delete B;
}
void FreeMatrix_C(int& rowsA, double** C)
{
  for(int i=0; i<rowsA; i++)
  {
    delete[] C[i];
  }
 delete C;
}
int main(int argc, char* argv[])
{
  //using namespace std;
  double** A;
  double** B;
  double** C;
  int rowsA=0, colsA=0, rowsB=0, colsB=0;
  
  intro();
  get_A(rowsA, colsA);
  get_B(rowsB, colsB);
  get_C(A, B, rowsA, colsA, colsB);
  FreeMatrix_A(rowsA, A);
  FreeMatrix_B(rowsB, B);
  FreeMatrix_C(rowsA, C);
  
  return 0;
}
Feb 6, 2013 at 11:23pm
65
66
67
68
void get_C(double** A, double** B, int& rowsA, int& colsA, int& colsB)
{
  using namespace std;
  double** C; //this makes a brand new variable 
111
112
113
114
115
116
int main(int argc, char* argv[])
{
  //using namespace std;
  double** A;
  double** B;
  double** C; //this is an entirely different variable 
Feb 6, 2013 at 11:27pm
How can I fix this?, I'm confused.
Pages: 12