0

i have a little problem with my college assignment. I don't really understand what's going on with pointers and reference. Could someone point me where I am making a mistake??

using namespace std;
int i, n, maax, *position;
void tablica()
{
    int tab[n];
    cout<<"enter data:"<<endl;
    for (i=0; i<n; i++)
    {
        cin>>tab[i];
    }
    maax = tab[0];
    for (i=0; i<n; i++)
    {
        if (maax<tab[i])
        {
            maax=tab[i];
            *position=i+1;
        }
    }
}

int main()
{
    cout<<"array size:"<<endl;
    cin>>n;
    tablica();
    cout<<"max el. position is: "<<&position<<endl;
    return 0;
}
cananos
  • 3
  • 1
  • does the assignment say that you need to store the input in an array? You do not need the array to get value and position of the max. – 463035818_is_not_an_ai Jan 20 '22 at 14:07
  • Variable `position` is not initialized to point to a valid block of memory (i.e., it is not set as the start address of a memory area that has been properly allocated beforehand). So with `*position` you are possibly attempting to make an illegal memory access. –  Jan 20 '22 at 14:11
  • `int tab[n];` -- This is not valid C++. Hopefully your college is not teaching that this is valid C++. Instead, this should be: `std::vector tab(n);` – PaulMcKenzie Jan 20 '22 at 14:19
  • please include the assignment in your question – 463035818_is_not_an_ai Jan 20 '22 at 14:30

3 Answers3

0

You shouldn't use global variables (see Are global variables bad?). int tab[n]; is not standard C++, its a variable length array that is only available as extension on some compilers (see Why aren't variable-length arrays part of the C++ standard?). The segfault is because you never allocate memory for the position, it is initialized because its a global, but it doesnt point to an int (see Is dereferencing a pointer that's equal to nullptr undefined behavior by the standard?).

You do not need any array to get the max value and position. And there is no need to use a pointer in your code. Determine the maximum value and position in the same loop that is reading the input and return the result from the function instead of using the global variable:

#include <iostream>

int tablica(int n) {
    std::cout<<"enter data:\n";
    
    int max = 0;
    int max_pos = 0;
    std::cin >> max;
    
    for (int i=1; i<n; i++) {
        int number = 0;
        std::cin>>number;        
        if (max<number) {
            max=number;
            max_pos = i;
        }
    }
    return max_pos;
}

int main()
{
    std::cout<<"input size:\n";
    int n;
    std::cin>>n;
    int position = tablica(n);
    std::cout<<"max el. position is: "<< position << "\n";
    return 0;
}
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    Please read the tiltle of the question. This is the task that the OP got. In your solution you do not return the max value, but the poisition and you do not pass an array by pointer and the position by reference. And you do not explain about Pointers and references. So, your answer seems to be a littel bit off here. Im am very sorry. – A M Jan 20 '22 at 14:23
  • @ArminMontigny If the question is so clear to you then ok. I didn't understand what the actual task is, asked for clarification, and when there was no reply wrote this answer. I don't think it is that off – 463035818_is_not_an_ai Jan 20 '22 at 14:25
  • Title says "function returns the max element. pass the array by the pointer and the pos. by the reference". Therefore my comment. – A M Jan 20 '22 at 14:27
  • @ArminMontigny I did read the title, though in the code no array is passed by pointer, nor is it needed to do it. Also OPs code doesn't pass `pos` by reference. They present two contradicting interpretations of their assignment, so I choose to interpret it freely. What the actual task is we can only guess – 463035818_is_not_an_ai Jan 20 '22 at 14:29
0

Look at what the function should do:

"function returns the max element. pass the array by the pointer and the pos. by the reference"

It should not read any array elements.
It should not receive or return values in global variables.
It should not use a pointer to the position.

It should be passed an array (as a pointer) and somewhere to store the maximum position (as a reference), and return the maximum value.

That is, its prototype should look like

int tablica(const int* input, int size, int& max_position)

and main should look something like this:

int main()
{
    int n = 0;
    cout << "Array size: " << endl;
    cin >> n;
    int* data = new int[n];
    for (int i = 0; i < n; i++)
    {
        cin >> data[i];   
    }
    int position = -1;
    int max_element = tablica(data, n, position);
    cout << "The maximum element is " << max_element << ", at index " << position << endl;
    delete [] data;
}

Implementing tablica left as an exercise.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
0

Sure we can help you a little bit. But the whole topic of pointers and references cannot be covered in a short answer here on SO. You need to read a book.

The following will be very simplified and there is much more in reality. But let's start with this simple explanantion.

Let me give you a typical example that is often used in C or very early C++ books. Look at the function swap that should exchange the values of 2 variables.

#include <iostream>

void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int a = 1, b = 2;
    swap(a, b);
    std::cout << "a: " << a << "\tb: " << b << '\n';
}

We hope that after the call to the function swap, "a" will contain 2 and "b" will be 1. But it is not. Because in this case (and per default) the variables that are given to the function swap, are passed by value. So, the compiler will generate some code and copies the value of variables "a" and "b" into some local internal storage, also accessible with the name "a" and "b". So, the original "a" and "b" will never be touched or modified. By passing a variable by value, a copy will be mdae. This is often intended, but will not work in this example.

The next development stage was the pointer. The pointer is also a variable that contains a value. But this time it is the address of another variable somehwere in memory. If you have a variable like int a=3; then the 3 is somewhere stored in memory (decided by the compiler of the linker) and you can access the memory region with the name "a".

A pointer can store the memory address of this variable. So not the value 3 of the variable "a", but the address of the variable "a" in memory. The pointer points to that memory region, where the 3 ist stored. If you want to access this value, then you need to dereference the pointer with the * operator. And to get the address of variable 'a', you can write &a. But how does this help?

It helps you indirectly to get modified or result values out of a function. Example:

#include <iostream>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int a = 1, b = 2;
    swap(&a, &b);
    std::cout << "a: " << a << "\tb: " << b << '\n';
}

In main we take the address of variable "a" and "b" and give this to the function. The address of the function (the pointer) will be given to the function as value now. A copy of the pointer will be made (not in reality) but this does not harm, because we can now modify the original values of the variable, by derefencing the pointer. Then the function ends and we will find the correct values in the original variables "a" and "b".

But, pointers are notoriously difficult to understand and very error prone. Therefore the "reference" has been invented. It is kind of an alias for a normal variable. And the good point is that if you pass a reference to the function, then you can modify immediately the original value. That makes things very convenient.

The function swap could then be written as

#include <iostream>

void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int a = 1, b = 2;
    swap(a, b);
    std::cout << "a: " << a << "\tb: " << b << '\n';
}

And this gives the intented result. And is by far simpler.


Now to your code. First, VLAs (variable length arrays), namely the int tab[n]; where 'n' is no compile time constant, are a not a ppart of the C++ language. You canot use them. You could and should use a std::vector instead, but you did not yet learn about it. So we will use new, to allocate some memory dynamically. Please note: In reality, new, raw pointers for owned memory and C-Style arrays should not be used. But anyway.

Then let us look at your requirements

function returns the max element. pass the array by the pointer and the pos. by the reference

So, we need a function to calculate the max element in an array, then return this value, and additionally copy the position of the max element in a variable, given to the function as reference. We will add an additional parameter for the size of the array, because we will not use VLAs here. The array will be given by pointer.

So the prototype of your function will be:

int getMaxElement(int *array, int sizeOfArray, int& positionOfMaxValue)

To implement such a function, we create an internal variable to hold the max value, which we will later return. Then, we compare all values in a loop against this max value and, if we find a bigger one, then we store this new result. As the initial value, we can simply take the first value of the array.

Example:

#include <iostream>

int getMaxElement(int* array, int sizeOfArray, int& positionOfMaxValue) {
    int resultingMaxValue = 0;
    if (sizeOfArray > 0) {
        resultingMaxValue = array[0];

        for (int i = 0; i < sizeOfArray; ++i) {
            if (array[i] > resultingMaxValue) {
                resultingMaxValue = array[i];
                positionOfMaxValue = i;
            }
        }
    }
    return resultingMaxValue;
}


int main() {
    // Get array size from user
    std::cout << "\nPlease enter the array size:  ";
    int arraySize = 0;
    std::cin >> arraySize;

    // Create an array
    int* array = new int[arraySize];

    // Read all values into the array
    for (int i = 0; i < arraySize; ++i)
        std::cin >> array[i];

    // Now calculate the max value and position of the max value
    int position = 0;
    int maxValue = getMaxElement(array, arraySize, position);

    // Show result
    std::cout << "\n\nResult:\nThe maximum value '" << maxValue << "' is at position " << position << '\n';

    delete[] array;
}

Please remember: This is a very simplified explanation

A M
  • 14,694
  • 5
  • 19
  • 44