0

I am having trouble figuring out how to fix an error WITHOUT changing anything in the main routine, as the instructions say. The compiler gives me an error on line 20, the line in the main routine that calls the findMax function, because ptr is being used without being initialized.

I don't understand why the compiler says that ptr is not being initialized, because in the findMax function, pToMax is set equal to arr.

I tried making pToMax a pointer to ptr by changing its initialization to int** pToMax and adding * to all subsequent instances of pToMax in the findMax function. However, after I did this, the compiler said that it cannot convert from int* to int** on line 20.

The only other fix I could think of would be to initialize int* ptr to nullptr in the main routine, but the instructions say I am not allowed to modify the main routine.

void findMax(int arr[], int n, int* pToMax)
{
    if (n <= 0) 
        return;      // no items, no maximum!

    pToMax = arr;

    for (int i = 1; i < n; i++)
    {
        if (arr[i] > *pToMax)
                pToMax = arr + i;
    }
}       

int main()
{
    int nums[4] = { 5, 3, 15, 6 };
    int* ptr;

    findMax(nums, 4, ptr);
    cout << "The maximum is at address " << ptr << endl;
    cout << "It's at position " << ptr - nums << endl;
    cout << "Its value is " << *ptr << endl;
}
6
  • 3
    You're passing pToMax by-value. Either return it as the function return value or pass it by address (int **ppToMax) and code it appropriately therein. Commented Nov 26, 2013 at 9:45
  • @WhozCraig, surely that is an answer? :) Commented Nov 26, 2013 at 9:46
  • 1
    @Moo-Juice until now I was staring at a C and C++ tag, and wasn't quite sure what the OP wanted. Thankfully, a half-dozen people will chime in with answers to cover bases no matter what, solidifying a strong indicator of the research put forth prior to posting this. Commented Nov 26, 2013 at 9:53
  • @WhozCraig: Ignore the tags, the use of cout kind of gives it away :) Commented Nov 26, 2013 at 9:56
  • To try an correct your misunderstanding, ptr in main is a different variable to ptr in findMax. Changing one has no efect on the other. Now some newbies think that because ptr is a pointer it's somehow special but this isn't true. You can use a pointer in one function to change what the pointer is pointing to in another function. But you can't change the pointer itself in another function. Commented Nov 26, 2013 at 9:59

2 Answers 2

5

findMax() is just modifying a local variable. You need to propagate that value back to the calling function some way - the simplest method is to pass it as a reference instead:

void findMax(int arr[], int n, int*& pToMax)
{
    // ...
} 
Sign up to request clarification or add additional context in comments.

4 Comments

@user2752992 if the instructions are as you say (an unmodifiable main()), this is the only way to do this.
Thank you, it worked. I'm still confused why, though. When I call findMax with ptr, int*& pToMax gets set to ptr. But isn't int*& pToMax basically the thing that the pointer to pToMax is pointing to, which is pToMax? But then of what type is pToMax? It must be a pointer if it can be set to ptr, but then why would it have an &? I'm sorry I don't know the technical lingo, but I am very confused
This is you basic misunderstanding, if you want to change an int like this you need a pointer to an int. If you want to change a pointer you need a pointer to a pointer (a double pointer). Now int*& pToMax is actually a reference to a pointer, but references and pointers are similar, and this is essentially a double pointer too.
@john THANKS I got it when you said "reference to a pointer".. I think my problem is that I need to think of pointers like any other variable type
1

findMax() should receive a pointer to pointer to int, instead of pointer to int, if you want to pass the pointer itself by reference. Remember that every value in C is passed by copy, meaning that you're passing a copy of ptr to findMax(). Inside findMax(), you may point it to somewhere else, but these changes will not be visible in main(). Thus, using ptr in main() results in undefined behavior when you print its address.

Use pointer to pointer to add another level of indirection, like this:

void findMax(int arr[], int n, int **pToMax)
{
    if (n <= 0) 
        return;      // no items, no maximum!

    *pToMax = arr;

    for (int i = 1; i < n; i++)
    {
        if (arr[i] > **pToMax)
                *pToMax = arr + i;
    }
}

The compiler complains about not being able to convert int * to int ** when you do this because ptr is of type int *. You need to use the referencing operator & to get a pointer to ptr and pass it to findMax():

int main()
{
    int nums[4] = { 5, 3, 15, 6 };
    int *ptr;

    findMax(nums, 4, &ptr);
    cout << "The maximum is at address " << ptr << endl;
    cout << "It's at position " << ptr - nums << endl;
    cout << "Its value is " << *ptr << endl;
}

That should fix it.

2 Comments

Correct of course, but the OP has said he can't change the main function.
Yeah, the question was tagged C, I don't think you can fix it without changing main if you're using C. With C++, your answer is, for sure, what he was looking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.