I'm trying to add elements of two arrays and store them in a third array. I'm experimenting with pointers so I want to use them as arguments to the user defined function.
When, I run the code, I get the Error: exited, segmentation fault, as soon as I enter the first two values for the array.
I am painfully unaware of what I'm doing wrong.
#include<iostream>
using namespace std;
float addarrays(float ptra1[5], float ptra2[5], float ptra3[5])
{
for(int i=0; i<5; i++)
{
ptra3[i] = ptra1[i] + ptra2[i];
}
return *ptra3;
}
int main()
{
float A[5], B[5], C[5];
float *ptA[5], *ptB[5], *ptC[5];
cout<<"Enter Array A: \n";
for(int i=0; i<5; i++)
{
cout<<"Element A["<< i <<"] = ";
cin>>*ptA[i];
}
cout<<"\nEnter Array B: \n";
for(int i=0; i<5; i++)
{
cout<<"Element B["<< i <<"] = ";
cin>>*ptB[i];
}
addarrays(*ptA, *ptB, *ptC);
cout<<"Displaying result for C[i] = A[i] + B[i]: \n";
for(int i=0; i<5; i++)
{
cout<<"\nElement C["<< i <<"] = "<<*ptC[i];
}
return 0;
}
For starters these arrays of pointers
float *ptA[5], *ptB[5], *ptC[5];
are not initialized.
So this statement
cin>>*ptA[i];
invokes undefined behavior.
You could set elements of the array ptA for example in a loop like
size_t i = 0;
for ( auto &p : ptA ) p = A + i++;
Pay attention to that the function addarrays does not set elements of the array ptC. In fact it tries to ser elements of the array C provided that the array ptC was correctly initialized. Array ptC is still uninitialized. So this statement
cout<<"\nElement C["<< i <<"] = "<<*ptC[i];
again will invoke undefined bejavior.
Thus you need to initialize the arrays of pointers.
size_t i = 0;
for ( auto &p :ptA ) p = A + i++;
i = 0;
for ( auto &p :ptB ) p = B + i++;
i = 0;
for ( auto &p :ptC ) p = C + i++;
The function can be declared and defined the following way
void addarrays(float * ptra1[], float * ptra2[], float * ptra3[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
*ptra3[i] = *ptra1[i] + *ptra2[i];
}
}
and called like
addarrays( ptA, ptB, ptC, 5 );
Related
need a better approach to pass address arr[0][2], given that is has to be received in a double pointer.
want to pass arr[0][2] without storing in any other variable.
#include <iostream>
using namespace std;
int help(int **arr)
{
cout<<**arr;
}
int main()
{
{
int n=3,m=3,k=0;
int **arr = new int*[n];
for(int i = 0; i < n; i++) {
arr[i] = new int[m];
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
arr[i][j]=k;
k++;
}
}
int *g=*arr+2;
int **h=&g;
help(h);
}
}
There is no better way. Unfortunately C++ syntax x[y] can be used to mean two very different operations: if x is an array then is indexing, if x is a pointer they it's indirection and indexing.
If a caller expects a pointer to a pointer and you've a bidimensional matrix there's nothing you can do except actually creating the pointer that is not present in the matrix and pass its address.
The fact that with an array of pointers, with a pointer to a pointer and with a 2d array the syntax to reach an element is x[y][z] is irrelevant... they are three very different operations.
Why not just write
int *p = &arr[0][2];
help( &p );
If you want to get an access to the whole array using a pointer of the type int ** then you can use the following approach.
#include <iostream>
void help(int **arr, size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
std::cout << ( *arr )[i] << ' ';
}
std::cout << '\n';
}
int main()
{
int arr[2][3]={{1,2,3},{4,5,6}};
int *p = reinterpret_cast<int *>( arr );
help( &p, 6 );
return 0;
}
The program output is
1 2 3 4 5 6
Something is wrong with this code as it modifies an array. All elements are assigned 0. But why ?? Here's the question of program:
Write a function named "subtotal" takes as its arguments the following:
(1) an array of floating point values;
(2) an integer that tells the number of cells in the array.
The function should replace the contents of each cell with the sum of the contents of all the cells in the
original array from the left end to the cell in question.
Thus, for example, if the array passed to the
function looks like this:
[0] [1] [2] [3] [4]
5.8 | 2.6 | 9.1 | 3.4 | 7.0
then when the function returns, the array will have been changed so that it looks like this:
[0] [1] [2] [3] [4]
5.8 | 8.4 | 17.5 | 20.9 | 27.9
because 5.8 + 2.6 = 8.4 and 5.8 + 2.6 + 9.1 = 17.5 and so on. Note that the contents of cell [0] are not
changed. The function should not return a value.
And here is the program which I've made:
#include<iostream>
using namespace std;
void subtotal(float*,int);
int main(void)
{
int n;
cout << "Enter the number of cells: ";
cin >> n;
float* cell;
cell = new float[n];
cout << "Enter the elements: ";
for(int i = 0; i < n; i++)
cin >> *(cell + i);
subtotal(cell, n);
for(int i = 0; i < n; i++)
cout << *(cell + i) << "|";
delete[] cell;
}
void subtotal(float* cell, int n)
{
int i, j;
for(i = 0; i < n; i++)
{
float sum = 0;
for(j = 0; j < i; j++)
{
sum += *(cell + j);
}
*(cell + i) = sum;
}
}
Why using nested loop? You can use only one loop so that the you'll iterate once is enough as long as you want only sum the consecutive elements so change the function subtotal to:
void subtotal(float* cell, int n)
{
for(int i = 0; i < n - 1; i++) // `n - 1` to avoid outband
{
float sum = cell[i] + cell[i + 1];
cell[i + 1] = sum;
}
}
Or if you want to do it using pointer like in your case:
void subtotal(float* cell, int n)
{
for(int i(0); i < n - 1; i++)
{
float sum = *(cell + i) + *(cell + i + 1);
*(cell + i + 1) = sum;
}
}
You should do j <= i in the inner loop. If you don't do that, the first new element in the array will be zero (summing over no elements at all). For the second element, it will only sum over the first, which is 0 again. Etc.
In addition, your code is very non-idiomatic. The normal way to address an array element is cell[i], not *(cell+i), although both ways are possible for plain arrays.
This is how your code should be:
#include<iostream>
using namespace std;
void subtotal(float*,int);
int main(void)
{
int n = 5;
float *cell=new float[n];
cell[0] = 5.8f;
cell[1] = 2.6f;
cell[2] = 9.1f;
cell[3] = 3.4f;
cell[4] = 7.0f;
subtotal(cell,n);
for(int i=0;i<n;i++)
cout<<*(cell+i)<<"|";
delete []cell;
}
void subtotal(float*cell,int n)
{
float * temp = new float [n];
int i,j;
for(i=0;i<n;i++)
{
float sum=0;
for(j=0;j<=i;j++) // Change here
{
sum+=*(cell+j);
}
*(temp+i)=sum; // Change here
}
for (int i =0; i < n; ++i) {
cell[i] = temp[i]; // Copy the values back
}
delete [] temp;
}
There are two problems with your subtotal function.
First, you should do j <= i in the inner loop.
Next, you should store the summation in a temporary array, else you are going to make changes to the original input after each subset sum and the output you will get will not be the desired one. You would have got output like this :
5.8|8.4|23.3|40.9|85.4|
However, with the changes I have proposed, you should get the desired output:
5.8|8.4|17.5|20.9|27.9|
corrected-code-here
I have written a function to raise matrix to a certain power.
But when running the code the result is the memory location not the actual values. I think the problem is with the pointers.
My code:
#include <iostream>
using namespace std;
typedef int array2d [2][2];
array2d A,B,r;
void pow(array2d* r,array2d C);
int main(){
array2d resa,resb;
A[0][0]=2;
A[0][1]=2;
A[1][0]=2;
A[1][1]=2;
B[0][0]=3;
B[0][1]=3;
B[1][0]=3;
B[1][1]=3;
r[0][0]=1;
r[0][1]=0;
r[1][0]=0;
r[1][1]=1;
pow(&resa,A);
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
cout<<resa[i][j]<<" ";
}
cout<<endl;
}
pow(&resb,B);
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
cout<<resb[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
void pow(array2d* r, array2d C)
{
array2d temp;
for(int w=0;w<3;w++)
{
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
temp[i][j]=0;
for(int k=0;k<2;k++)
temp[i][j]+=(*r)[i][k]*C[k][j];
}}
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
(*r)[i][j]=temp[i][j];
}}
}
}
How can I solve this problem.
Thank You.
Your error has nothing to do with pointers or addresses, but your algorithms is erroneous:
pow(&resa, A);
multiplies the matrix A with the uninitialized matrix resa which can yield any number of possible results.
The quick and dirty fix would be to initialize resa and resb as identity matrices:
array2d resa = { { 1, 0 }, { 0, 1 } };
array2d resb = { { 1, 0 }, { 0, 1 } };
EDIT or slightly better: Initialize r inside of pow
//passing r by pointer is not actually necessary here,
//but I don't want to modify too much of the code
(r*)[0][0] = 1;
(r*)[1][0] = 0;
(r*)[0][1] = 0;
(r*)[1][1] = 1;
The more elegant solution would be to first multiply the parameter C with itself, store the result in r and then go on with your algorithm.
On a side note: don't use c-style arrays, if you don't need them (especially not in typedefs). Use std::array instead, which will get rid of most of the confusion regarding to parameter passing.
you really should avoid global when you can, and using the same name in global and local variables is even worse
also the name of your variables MATTERS, here i call the input matrix IN and output matrix OUT (ok "n" should be called power)
using namespace std;
typedef int array2d [2][2];
void display( array2d a ) ;
void pow(array2d IN ,array2d OUT , int n);
int main()
{
array2d A,B;
array2d resa,resb;
A[0][0]=2;
A[0][1]=2;
A[1][0]=2;
A[1][1]=2;
B[0][0]=3;
B[0][1]=1;
B[1][0]=2;
B[1][1]=1;
pow (A , resa , 5);
pow( B , resb, 2 ) ;
return 0;
}
and
void pow(array2d IN, array2d OUT , int n )
{
for( int i = 0 ; i < 2 ; ++ i )
for( int j = 0 ; j < 2 ; ++ j )
OUT[i][j] = ( i == j ) ;
display( OUT ) ;
array2d temp;
for(int w=0;w<n;w++)
{
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
temp[i][j]=0;
for(int k=0;k<2;k++)
{
temp[i][j]+=OUT[i][k]*IN[k][j];
}
}
}
for(int i=0;i<2;i++){
for(int j=0;j<2;j++)
{
OUT[i][j]=temp[i][j];
}
}
display( OUT ) ;
}
}
with
void display( array2d a )
{
cout << endl ;
for( int i = 0 ; i < 2 ; ++ i )
{
for( int j = 0 ; j < 2 ; ++ j )
cout << a[i][j] << " " ;
cout << endl ;
}
}
The first parameter of your pow function, change it to the pass by reference: void pow(array2d &r,array2d C);
Then where you call it, call it like so: pow(resa,A);
Finally, you don't need to deference r in your pow function now, so (*r)[i][j]=temp[i][j]; can be changed to r[i][j]=temp[i][j];
I think this is what you wanted to do. ( pass by reference )
( I am not in front of a pc where I can test this right now, will confirm as soon as I can, and maybe flesh out why this is better ( can read up about pointers, heap memory and pass by reference )
#include <iostream>
#include <cstdlib>
using namespace std;
void swapNum(int *q, int *p)
{
int temp;
temp = *q;
*q = *p;
*p = temp;
}
void reverse(int *ip, int const size)
{
for (int k = 0; k < size; k++)
{
if (k == (size/2))
{
int *q = &ip[k];
int *p = &ip[k+1];
swapNum(q,p);
break;
}
else
swap(ip[k], ip[size-k]);
}
}
int main()
{
const int size = 20;
int arr[size];
int *ip;
ip = arr;
cout << "Please enter 20 different numbers." << endl;
for (int i = 0; i < size; i++)
{
cout << "\nNumber " << i+1 << " = ";
cin >> ip[i];
}
reverse(ip, size);
cout << "I will now print out the numbers in reverse order." << endl;
for (int j = 0; j < size; j++)
{
cout << ip[j] << " ";
}
return 0;
}
When I try to run this program it crashes. I don't know what's wrong and the purpose of my program is to swap number of the array using pointers. I am recently introduced to this so I am not that familiar with it. But I think that I am swapping the address of the numbers instead of swapping the numbers in the address. Correct me if I am wrong.
You're accessing outside the array bounds in reverse() when you do:
swap(ip[k], ip[size-k]);
On the first iteration of the for loop, k is 0 and size-k is size. But array indexes run from 0 to size-1. So it should be:
swap(ip[k], ip[size-k-1]);
But I don't see a definition of swap in your program. I think it should actually be:
swapNum(&ip[k], &ip[size-k-1]);
Another improvement: Instead of handling size == k/2 specially and using break, just use size < k/2 as the bound test in the for loop.
swap(ip[k], ip[size-k]);
Your problem is there. size - k when k is 0 will lead to undefined behavior (accessing an array out of bounds). Your loop structure in reverse can be simplified:
for (int k = 0; k < size / 2; k++)
swapNum(&ip[k], &ip[size - k - 1]); // updated to use the address since your swap function takes pointers.
Function reverse is invalid
void reverse(int *ip, int const size)
{
for (int k = 0; k < size; k++)
{
if (k == (size/2))
{
int *q = &ip[k];
int *p = &ip[k+1];
swapNum(q,p);
break;
}
else
swap(ip[k], ip[size-k]);
}
}
For example when k is equal to 0 then you call
swap(ip[0], ip[size]);
However the array has no element with index size.
ALso you mess two functions std::swap and swapNum
This code snippet also is invalid
if (k == (size/2))
{
int *q = &ip[k];
int *p = &ip[k+1];
swapNum(q,p);
break;
}
When size is an even number (or an odd number) as in your code then you make incorrect swap. For example if size is equal to 20 then you should swap ip[9[ with ip[10]. However according to the code snippet above you swap ip[10] with ip[11].
You could use standard algorithm std::reverse
for example
#include <algorithm>
#include <iterator>
//...
std::reverse( std::begin( arr ), std::end( arr ) );
or
#include <algorithm>
//...
std::reverse( arr, arr + size );
If you want to write the function yourself then it could look as
void reverse( int a[], int size )
{
for (int k = 0; k < size / 2; k++)
{
int tmp = a[k];
a[k] = a[size-k-1];
a[size-k-1] = tmp;
}
}
Or if you want to use your function swapNum then
void reverse( int a[], int size )
{
for (int k = 0; k < size / 2; k++)
{
swapNum( &a[k], &a[size-k-1] );
}
}
EDIT: I removed qualifier const from the first parameter that was a typo.
I am learning pointers so I tried to implement this simple code of finding Max, min and Avg of student grades.
I only could found the avg BUT for the Max and the Min I got the first element of the *p.
here is my code If you please can tell me what is my mistake
#include <iostream>
using namespace std;
int main()
{
int *p;
int x;
cout << "Enter a number of student: ";
cin >> x;
p = new int[x];
for (int i = 0; i < x; i++)
{
cout << "Enter a grade: ";
cin >> *(p + i);
}
int sum = 0;
int max = 0;
int min = 0;
max = *p;
min = *p;
for (int i = 0; i < x; i++)
{
if (min > *p)
{
min = *p;
p++;
}
}
for (int i = 0; i < x; i++)
{
if (max < *p)
{
max = *p;
p++;
}
}
for (int i = 0; i < x; i++)
{
sum += *p;
p++;
}
int avg = sum / x;
cout << "avg is : " << avg << endl;
cout << "Max num is : "<< max
<< "\n Min num is : " << min << endl;
}
Note the changes
for (int i = 0; i < x; i++)
{
if (min > *(p+i))
{
min = *(p+i);//changed
}
}
for (int i = 0; i < x; i++)
{
if (max < *(p+i))
{
max = *(p+i);//changed
}
}
for (int i = 0; i < x; i++)
{
sum += *(p+i);//changed
}
You only advance the pointer, if *p is greater than the current max or min. Either advance it on every iteration (and back up the original state) or use p[i] to get the element of the iteration.
Your code is wrong on a number of levels. First of all, have a look at how you initialize the pointer p, which is supposed to point to the beginning of your array containing int elements :
p = new int[x];
This is all good. However, if you now take a look at the first loop...
for (int i = 0; i < x; i++)
{
if (min > *p)
{
min = *p;
p++;
}
}
You will notice that you keep incrementing p, which was supposed to point to the beginning of the array. This way, you can't possibly visit every element of the array when you run the second loop, because p does not point at the start of your array anymore! Thus, you invoked what some people call undefined behaviour by accessing an array out of its bounds.
However, you were able to properly reference the array in the loop where you actually write the elements to it - with the line cin >> *(p + i);.
Also, you should always remember to delete everything you newed. However, if you lose the pointer to what new returned, you will never be able to successfully delete it.
Furthermore, if you're programming in C++, you really should avoid using raw pointers, and - if you really need to - wrap them inside an unique_ptr (if you're using C++11). When it comes to "dynamic arrays", std::vector is most often the better way.
That's because you're doing p++, thus "losing the pointer".
In each for loop except for the first one, change *p to p[i], and get rid of the p++.
Also, at the end of the function, call delete p.
You could inline the calculation of max, min, and sum:
int sum = 0;
int max = 0;
int min = 0;
for (int i = 0; i < x; i++)
{
int g=0;
cout << "Enter a grade: ";
cin >> g;
if (g > max)
max = g;
if (g < min)
min = g;
sum += g;
}
Then you wouldn't need p = new int[x]