Search code examples
c++arrayspointerscastingpass-by-value

C++ returning pointer using parameter - comparison between distinct pointer types lack a cast


I'm trying to create a function called void find(int id, Student** s) that searches the array for the student with the id specified in parameter id, and returns that student pointer using parameter s. The task says I must use the parameter to return this data and to not use the return value.

I'm a little confused by what the last line means. I have this so far but the s == students[i] line causes the error: comparison between distinct pointer types ‘Student**’ and ‘Student*’ lacks a cast [

void StudentsArray::find(int id, Student** s){
    for(int i = 0; i < studentsCount; ++i){
        if(students[i]->getId() == id){ 
            s=students[i];
        }
    }
}

I'm just a little confused on what I'm supposed to return and how I would go about doing so and would appreciate any help!


Solution

  • The second argument in the function says "A pointer to a pointer to Student"

    To return it, you'll need to set it to a pointer of Student. Taking a pointer of one of the student array is done like this: &student[i].

    Once you have the pointer, you need to store somewhere, and you'll store it inside the given pointer-to-pointer by dereferencing it like this: *s

    Put together, you'll need to *s = &student[i] to perform: "store in the memory area pointed by s the address of the student's item"

    void StudentsArray::find(int id, Student** s){
        *s = nullptr;
        for(int i = 0; i < studentsCount; ++i){
            if(students[i]->getId() == id){ 
                *s = &students[i];
            }
        }
    }
    

    If this is disturbing at first, just remove a layer of indirection by writing:

       void StudentsArray::find(int id, Student* & s) {
          ...
          s = &student[i];
          ...
       } 
    

    In that case, you are taking a reference (so if you modify it inside the function you're modifying it from the caller's site) to a pointer to student. When you assign it, it's like it's returned to the caller.

    Why it's important

    Sometimes, you need to be able to return more than one thing from a function. Either you build a structure holding the things and you return that but it's very painful to do and usually not very efficient, either you simply accept a pointer (or a reference) to these things and expect the function to fill them for you. From my own experience, this is what is done most of the time.

    EDIT: Following remark from Tanveer Badar, it's good practice to expect the function to set the returned value to 0 (or better nullptr) if not found so you don't have to do it on the caller's site.