Finding Max, Min, Avg using dynamic memory allocation and pointers - c++

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]

Related

what's wrong with this "maximum-minimum element in an array" Logic?

I am new to coding and I am unable to see what is wrong with this Logic.
I am unable to get the desired output for this program.
The Question is to find the minimum and maximum elements of an array.
The idea is to create two functions for minimum and maximum respectively and have a linear search to identify the maximum as well as a minimum number.
#include <iostream>
#include<climits>
using namespace std;
void maxElement(int a[], int b)
{
// int temp;
int maxNum = INT_MIN;
for (int i = 0; i < b; i++)
{
if (a[i] > a[i + 1])
{
maxNum = max(maxNum, a[i]);
}
else
{
maxNum = max(maxNum, a[i+1]);
}
// maxNum = max(maxNum, temp);
}
// return maxNum;
cout<<maxNum<<endl;
}
void minElement(int c[], int d)
{
// int temp;
int minNum = INT_MAX;
for (int i = 0; i < d; i++)
{
if (c[i] > c[i + 1])
{
minNum = min(minNum,c[i+1]);
}
else
{
minNum = min(minNum,c[i]);
}
// minNum = min(minNum, temp);
}
// return minNum;
cout<<minNum<<endl;
}
int main()
{
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
minElement(arr,n);
maxElement(arr,n);
return 0;
}
You are already comparing each element to the current max / min. It is not clear why in addition you compare to adjacent elements. Trying to access a[i+1] in the last iteration goes out of bounds of the array and causes undefined behavior. Just remove that part:
void maxElement(int a[], int b)
{
// int temp;
int maxNum = INT_MIN;
for (int i = 0; i < b; i++)
{
maxNum = max(maxNum, a[i]);
}
cout<<maxNum<<endl;
}
Similar for the other method.
Note that
int n;
cin >> n;
int arr[n];
is not standard C++. Variable length arrays are supported by some compilers as an extension, but you don't need them. You should be using std::vector, and if you want to use c-arrays for practice, dynamically allocate the array:
int n;
cin >> n;
int* arr = new int[n];
Also consider to take a look at std::minmax_element, which is the standard algorithm to be used when you want to find the min and max element of a container.
Last but not least you should seperate computation from output on the screen. Considering all this, your code could look like this:
#include <iostream>
#include <algorithm>
std::pair<int,int> minmaxElement(const std::vector<int>& v) {
auto iterators = std::minmax_element(v.begin(),v.end());
return {*iterators.first,*iterators.second};
}
int main()
{
int n;
std::cin >> n;
std::vector<int> input(n);
for (int i = 0; i < n; i++)
{
std::cin >> input[i];
}
auto minmax = minmaxElement(input);
std::cout << minmax.first << " " << minmax.second;
}
The method merely wraps the standard algorithm. It isnt really needed, but I tried to keep some of your codes structure. std::minmax_element returns a std::pair of iterators that need to be dereferenced to get the elements. The method assumes that input has at least one element, otherwise dereferencing the iterators is invalid.

C6385 warning in VS (in regard to dynamic arrays)

My code is supposed to print the Union and Intersection of two sets of integers.
Why do I get this warning?
Is it because I use dynamic arrays and it's size could be anything in runtime?
How can I fix it? My code works fine but this warning really bugs me.
P.S: I know it would be a lot easier to use std::vector but my teacher required to use arrays.
#include <iostream>
using namespace std;
void UnionFunc(int[],int,int[],int,int[],int&);
void IntersectionFunc(int[], int, int[], int, int[], int&);
int main() {
int* A;
int SizeA;
int* B;
int SizeB;
int* Union;
int UnionSize=0;
int* Intersection;
int IntersectionSize=0;
cout << "Enter the Size of First Set : "; cin >> SizeA;
A = new int[SizeA];
cout << "Enter the Size of Second Set : "; cin >> SizeB;
B = new int[SizeB];
Intersection = new int[SizeA >= SizeB ? SizeB : SizeA];
Union = new int[SizeA + SizeB];
for (int i = 0; i < SizeA; i++) {
cout << "Set A[" << i + 1 << "] = ";
cin >> A[i];
}
for (int i = 0; i < SizeB; i++) {
cout << "Set B[" << i + 1 << "] = ";
cin >> B[i];
}
UnionFunc(A,SizeA,B,SizeB,Union,UnionSize);
IntersectionFunc(A, SizeA, B, SizeB, Intersection, IntersectionSize);
cout <<endl<< "Union Set : ";
for (int i = 0; i < UnionSize; i++) {
cout << Union[i] << ",";
}
cout <<endl <<"Intersection Set : ";
for (int i = 0; i < IntersectionSize; i++) {
cout << Intersection[i] << ",";
}
system("pause>n");
return 0;
}
void UnionFunc(int A[],int SizeA, int B[],int SizeB, int Union[],int &UnionSize) {
//Adding First Array to Union Array
for (int i = 0; i < SizeA;i++) {
Union[i] = A[i];
UnionSize++;
}
//Checking if second array's elemnts already exist in union arry, if not adding them
bool exist;
for (int i = 0; i < SizeB; i++) {
exist = false;
for (int j = 0; j < UnionSize; j++) {
if (B[i] == Union[j] ) {
exist = true;
}
}
if (exist == false) {
Union[UnionSize] = B[i];
UnionSize++;
}
}
}
void IntersectionFunc(int A[], int SizeA, int B[], int SizeB, int Intersection[], int& IntersectionSize) {
for (int i = 0; i < SizeA; i++) {
for (int j = 0; j < SizeB; j++) {
if (A[i] == B[j]) {
Intersection[IntersectionSize] = A[i];
IntersectionSize++;
}
}
}
}
Is it because I use dynamic arrays and it's size could be anything in
runtime?
Yes! The compiler doesn't know (and, as your code is written, can't know) that both SizeA and SizeB will be 'valid' numbers - so the size of the three int arrays you create could be less than is required for the Intersection[i] 'read' to be valid.
A 'quick and dirty' fix for this is to provide a visible guarantee to the compiler that the arrays you create will be at least a certain size, like this:
A = new int[max(1,SizeA)]; // Compiler can now 'see' a minimum size
And similarly for the other allocations you make with the new[] operator.
(I have tested this with VS2019, adding the max(1,SizeA) and max(1,SizeB) 'fixes' to just the allocations of A and B and the warning is removed.)

Function is not returning any value | C++

I'm writing a function that will find the number with max number of divisors but the function is not returning anything. Can someone point out my mistake?
This is the question
Write a C++ program that creates and integer array having 30 elements. Get input in this array (in main
function). After that, pass that array to a function called “Find_Max_Divisors” using reference pointer.
The function “Find_Max_Divisors” should find (and return) in the array that number which has highest
number of divisors. In the end, the main function displays that number having highest number of divisors.
#include <iostream>
using namespace std;
int main ()
{
int arr[30];
int* array = &arr[30];
cout << "Please enter values of the array" << endl;
for (int i=0; i<30; i++)
{
cin >> arr[i];
}
cout << "Number with most divisors in array is " << endl;
int Find_Max_Divisors (*array);
}
int Find_Max_Divisors (int p[])
{
int count=0, max_divisor, max_counter, prev=0, repeat=0, divisor;
for (int i=2; i<=30; i++)
{
if (p[i]%i==0)
{
count++;
}
if (count > prev)
{
prev = count;
divisor = p[i];
}
if (count==max_counter && max_counter!=0)
{
cout << p[i] <<" has maximum of "<< count <<" divisors.\n";
}
max_counter = prev;
max_divisor = divisor;
repeat++;
}
return count;
}
change
int Find_Max_Divisors (*array);
to
int value = Find_Max_Divisors(arr);
You can get rid of the array variable altogether.
It's quite possible you'll find you need to put your function before main, too.
Firstly, you declare an array that has 30 elements
int arr[30];
But here you make the pointer point to the out of arr.
int* array = &arr[30];
I guess you want to make pointer point to arr, if i am not wrong, you can do as:
int *array = &arr[0]; // or int * array = arr;
Then when you call the Find_Max_Divisors function, you should change to:
int return_value = Find_Max_Divisors(array);
One more thing, int this function:
for (int i=2; i<=30; i++)
When i=30, p[i] go to out of bount again. It should be:
for (int i=2; i< 30; i++)
you don't need pointers to do that this simple code can fix your problem just change the size of your array as you want i am testing with array of size 4 here
#include <iostream>
using namespace std;
int Find_Max_Divisors(int p[])
{
int count = 0, max = 0;
for (int i = 0; i < 4; i++) {
for (int j = 1; j < p[i] / 2; j++) {
if (p[i] % j == 0) {
count++;
}
}
if (count > max)
max = p[i];
}
return max;
}
int main()
{
int arr[30];
// int* array = &arr[30];
cout << "Please enter values of the array" << endl;
for (int i = 0; i < 4; i++) {
cin >> arr[i];
}
int value = Find_Max_Divisors(arr);
cout << "Number with most divisors in array is " << value << endl;
}
There are several mistakes in your code:
First, if your main function should know the funtions it calls, you should declare them previously. Just add a line Find_Max_Divisors (int p[]); Before the main function.
An array in C or C++ is a pointer, when you only call it by it's name. So call Find_Max_Divisors (arr) and get rid of that awful pointer-assignment.
In the last line just try to call the function, but never put it to stdout, you should change it to this:
cout << "Number with most divisors in array is " << Find_Max_Divisors(arr) << endl;
What you actually did with int Find_Max_Divisors (*array); was declaring a new variable and not calling a function.

Why it doesn't swap two integers in an array?

#include <iostream>
using namespace std;
int main()
{
int A[6]={3,7,9,4,6,1};
int max;
max = A[0];
for(int i=0; i< 6; i++)
{
if(A[i] > max)
{
max = A[i];
}
}
//cout << max <<"\n";
int temp;
temp=A[0];
A[0]=max;
max = temp;
for(int i=0;i<6;i++)
{
cout << A[i] << endl;
}
return 0;
}
I want to swap the maximum value with the first one in the decared array but it only replaces 1st value with maximum while maximum value is also retained at its position.
The logic is slightly wrong. You are actually swapping the values of variable max instead of the element with the max value.
If you want to swap the element with max value, keep track of its position, like this:
if(A[i] > max)
{
max = A[i];
pos = i;
}
And while swapping, use it as follows:
int temp;
temp=A[0];
A[0]=A[pos];
A[pos] = temp;
Note: An alternative way is to use pointers, this is just a simple non-pointer method.
You're swapping A[0] with the variable max, not the array element you took its value from.
You could make max a pointer, so that it can be used to access the array element; or you could remember the array index that the value came from. Or you could use the standard library:
swap(A[0], *max_element(begin(A), end(A)));
max is just an integer, it doesn't point to any location in the array, so assigning it will not change the array. You could change max to be a pointer so that changing it changes the value it points to:
int main()
{
int A[6]={3,7,9,4,6,1};
int *max;
max = &A[0];
for(int i=0; i< 6; i++)
{
if(A[i] > *max)
{
max = &A[i];
}
}
int temp;
temp=A[0];
A[0]=*max;
*max = temp;
for(int i=0;i<6;i++)
{
cout << A[i] << endl;
}
return 0;
}

C++ How to change the output on a new array

So I wrote a program that is supposed select the perfect squares from an array and put it into another array. Example: (2,4,13,5,25,66) and the second array(the result) should look like this (4,25)
My result looks like this (0,4,0,0,25,0) ...so its half good ...how to make it show only 4,25 ?
#include<iostream.h>
#include<math.h.>
int main()
{
int A[100],i,n,p,j;
cout << "Number of array elements=";
cin >> n;
for(i=1;i<=n;i++)
{
cout<<"A["<<i<<"]=";
cin>>A[i];
}
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
A[j]=A[i];
else
A[i]=0;
cout << A[i] << " ";
}
return 0;
}
USING ONLY c++ basic commands...as i did
You need to keep a separate count of how many perfect squares you've found and use that to place your answers into an array of perfect squares:
int squares[???];
// ...
if(p*p==A[i]) {
squares[squaresFound]=A[i];
squaresFound++;
}
The problem now will be to decide how long the squares array should be. You don't know ahead of time how many squares you're going to get. Are you going to have it the same size as A and fill the rest with 0s? Or do you want the array of squares to be exactly the right size?
If you want it to be the right size, you're much better off using a std::vector:
std::vector<int> squares;
// ...
if(p*p==A[i]) {
squares.push_back(A[i]);
}
But I think your silly "only basic C++ commands" restriction will not allow you to do this.
You talk about a second array (the result), yet your code declares only one array! Additionally, you reference A[j], but your j has not be initialized.
You should declare another array B[100], initialize j to zero, and then use this code when you find a square:
int j = 0;
for (int i=0 ; i != n ; i++) {
int p = sqrt(A[i]);
if(p*p==A[i]) {
B[j++] = A[i];
}
}
Make another array, remove all occurrences of 0 from the resultArray and add non-0 to newArray.
OR
int j=0
if(A[i]==p*p)
squares[j++]=A[i];
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int A[100];
int n;
cout << "Number of array elements = " << endl;
cin >> n;
for(int i = 0; i < n; i++)
{
cout << "A[" << i << "] = ";
cin >> A[i];
}
int B[100];
int cnt_sqr = 0;
for(int i = 0; i < n; i++)
{
int p = sqrt(A[i]);
if (p * p == A[i])
{
B[cnt_sqr++] = A[i];
}
}
for (int i = 0; i < cnt_sqr; i++)
{
cout << B[i] << ' ';
}
return 0;
}
Full code of that about what you were told above
If you do not want to modify your code you can write the following:
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
{
cout << A[i] << " ";
}
}
It will print you only perfect squares.
If you want to copy elements to another array:
int squares[100] = {0}; // Assuming that all values can be perfect squares
int square_count = 0;
for(i=1;i<=n;i++)
{
p=sqrt(A[i]) ;
if(p*p==A[i])
{
squares[square_count++] = A[i];
}
}