Unable to find the largest element in array using Dynamic Memory Allocation

So I've gone over my code and tried looking at archives but I'm not sure where I'm going wrong. When I use the following code, it gives me the largest index number's value and not the largest value itself.

The answer should technically be:

"The largest element in the array is 97" [index 7]

but it always gives me 57 [index 9]. Or whatever number I put as the last element in the array.

[Info: I'm new to Dynamic Memory Allocation. This is a practice problem I'm trying to solve]

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

#include<iostream>

int* maxArrayElement(int arr[]);
int main(int argv, char** argc)
{
	//Write a program to find the largest element in an array using Dynamic Memory Allocation
	int *hArr = new int[10];
	for (int idx = 0; idx < 10; ++idx)
	{
		hArr[0] = 89;
		hArr[1] = 12;
		hArr[2] = 34;
		hArr[3] = 56;
		hArr[4] = 93;
		hArr[5] = 45;
		hArr[6] = 66;
		hArr[7] = 97;
		hArr[8] = 11;
		hArr[9] = 57;
	}

		int* finMax = maxArrayElement(hArr);
		std::cout << "The largest element in the array is " << *finMax << std::endl;
	
	delete[] hArr;
}
int* maxArrayElement(int arr[])
{
	int *largestSoFar = nullptr;
	for (int idx = 0; idx < 10; ++idx)
	{
		if (&(arr[idx]) > largestSoFar)
			largestSoFar = (&(arr[idx]));
	}
	return largestSoFar;
}
you are finding the largest pointer, not the largest value. It is critical to your understanding that you SEE that error looking at your code carefully and knowing now what to look for.
consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

int maxArrayElement(int arr[])
{
	int largestSoFar = arr[0];
	for (int idx = 1; idx < 10; ++idx)
	{
		if (arr[idx] > largestSoFar)
			largestSoFar = arr[idx];
	}
	return largestSoFar;
}

or if you DO want a pointer:
int* maxArrayElement(int arr[])
{
	int *largestSoFar = arr;
	for (int idx = 1; idx < 10; ++idx)
	{
		if (arr[idx] > *largestSoFar)
			largestSoFar = (&(arr[idx]));
	}
	return largestSoFar;
}


Last edited on
Thank you so much! I was successful when I tried the second method (I really want to use a pointer and practice that topic more). I understood the mistake I made in the for loop. But I still don't get why using "nullptr" didn't work. I tried running the code with "nullptr" instead of "arr" and it threw an error^.

^
Exception thrown: read access violation.
**largestSoFar** was nullptr.

Type: 0xC0000005
^

Could you please explain why? [I'm new to using nullptr too; as I understand it, it is a null value that can be equated with a pointer]
my code would not work setting it to nullptr for multiple reasons.

first, the key one, is that it dereferences the pointer. You cannot dereference nullptr, it will crash most OS immediately and is always an error.

Second, I started at the first one, not the 0th. The skipped iteration is not significant for performance etc, but it handles edge cases better like negative numbers (so if you set it to zero and they are all negative, you get 0 instead of your largest value!).
my logic says to pick off the first value in the list and update only if it finds one bigger than the first one, else the biggest is the first one by default.

so lets look at it again with comments on those ideas:

1
2
3
4
5
6
7
8
9
10
11
12
13
int* maxArrayElement(int arr[])
{
	int *largestSoFar = arr; // LSF is now a pointer to the first item in arr, eg 89 in your example.
	for (int idx = 1; idx < 10; ++idx) //starts at 1, LSF already looked at and absorbed [0]
	{
		if (arr[idx] > *largestSoFar) //deref of LSF: * means to go to the value it points to.
//if you init LSF to nullptr, the above line will crash/fail / undefined behavior problems 
//even if nullptr worked, it would SKIP the first item and give the wrong result.  
			largestSoFar = (&(arr[idx]));  
	}
	return largestSoFar;
}


you can code around it so you init to nullptr and iterate from zero. Its just more code to do it... you have to put something in like if LSF == nullptr then LSF = pointer to current item else ...

its a topic for another day but the concept of defaulting items to avoid conditions is a good performance tweak at times and it also simplifies code often.
eg instead of
int x{0};
...
if(y == 3) x =10;
else
x = 11;
is much easier to say
int x {11};
if(y==3) x = 10; //else, its 11, you already set it to that. I am using this idea above, though its not as easy to see in the routine.
Last edited on
Topic archived. No new replies allowed.