Thread: Need more help with pointers...

  1. #1
    SnoopFrogg KingFlippyNips's Avatar
    Join Date
    Sep 2016
    Posts
    33

    Need more help with pointers...

    I'm working on the practice problems in the Jumping into C++ book and I'm running into a segmentation fault when running my program.

    The problem is as followed: "Modify the program you wrote for exercise 1 so that instead of always prompting the user for a last name, it does so only if the caller passes in a NULL pointer for the last name."

    The problem they are talking about is: "Write a function that prompts the user to enter his or her first name and last name, as two separate values. This function should return both values to the caller via additional pointer (or reference) parameters that are passed to the function. Try doing this first with pointers and then with references. (Hint: the function signature will look be similar to the swap function from earlier!)"

    Here is my solution to the new problem:
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    string name(string *pFname, string *pLname);
    
    int main(){
    
        string firstName;
        //string lastName= NULL;
        //cout << "Nice to meet you " << name(&firstName, &lastName);
        cout << "Nice to meet you " << name(&firstName, NULL);
        return 0;
    }
    
    string name(string *pFname, string *pLname){
    
        cout << "Please enter your first name: ";
        getline(cin, *pFname);
        if(pLname){
            cout << "Please enter your last name: ";
            getline(cin, *pLname);
        }
        string fullName = (*pFname) + " " + (*pLname);
        return fullName;
    }
    The program allows me input the first name and then it seg faults. I'm a bit confused and would really appreciate if someone can point me into the right direction. Thanks!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,067
    I think you missed the "not" in the description.

    Anyway, if there is no last name, then the full name cannot be constructed from the last name.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    SnoopFrogg KingFlippyNips's Avatar
    Join Date
    Sep 2016
    Posts
    33
    Quote Originally Posted by laserlight View Post
    I think you missed the "not" in the description.

    Anyway, if there is no last name, then the full name cannot be constructed from the last name.
    Can you explain please? I'm still a bit confused.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,067
    That's the conceptual overview of what's happening. Here's what you are doing:
    Code:
    print the first name prompt
    read a line for the first name
    if there is space for the last name
        print the last name prompt
        read a line for the last name
    full name = first name + space + last name
    return full name
    So, what you are saying is: if there is no space for the last name, we're still going to construct the full name using the last name. Yeah, no last name, we're going to force the full name to contain the last name, too bad, we're doing it anyway. Obviously, that doesn't make sense.

    In C++ terms, what you are doing is dereferencing a null pointer: if pLname is a null pointer, then this line:
    Code:
    string fullName = (*pFname) + " " + (*pLname);
    results in undefined behaviour because *pLname dereferences a null pointer. Therefore, it is wrong.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    SnoopFrogg KingFlippyNips's Avatar
    Join Date
    Sep 2016
    Posts
    33
    Quote Originally Posted by laserlight View Post
    So, what you are saying is: if there is no space for the last name, we're still going to construct the full name using the last name. Yeah, no last name, we're going to force the full name to contain the last name, too bad, we're doing it anyway. Obviously, that doesn't make sense.

    In C++ terms, what you are doing is dereferencing a null pointer: if pLname is a null pointer, then this line:
    Code:
    string fullName = (*pFname) + " " + (*pLname);
    results in undefined behaviour because *pLname dereferences a null pointer. Therefore, it is wrong.
    Correct me if I'm wrong, but are you basically saying that I need to reference the null pointer instead of dereferencing something that is already null?

  6. #6
    SnoopFrogg KingFlippyNips's Avatar
    Join Date
    Sep 2016
    Posts
    33
    I tried approaching the problem using references instead of pointers and it seems to work just fine.

    Code:
    #include <iostream>
    #include <string>
     
    using namespace std;
    
    void name(string &ref_Fname, string &ref_Lname);
     
    int main(){
     
        string firstName;
        string lastName;
        name(firstName, lastName);
        cout << "Nice to meet you " << firstName << " " << lastName;
        return 0;
    }
     
    void name(string &ref_Fname, string &ref_Lname){
     
        cout << "Please enter your first name: ";
        cin >> ref_Fname;
        cout << "Please enter your last name: ";
        cin >> ref_Lname;
    }
    I would like to figure out how to solve this using pointers, but I keep running into that seg fault.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,067
    Quote Originally Posted by KingFlippyNips
    Correct me if I'm wrong, but are you basically saying that I need to reference the null pointer instead of dereferencing something that is already null?
    What do you mean by "reference the null pointer"?

    I am saying that you need to take into account the possibility that the pointer could be a null pointer.

    Actually, let's back up a bit. You wrote:
    Quote Originally Posted by KingFlippyNips
    The problem is as followed: "Modify the program you wrote for exercise 1 so that instead of always prompting the user for a last name, it does so only if the caller passes in a NULL pointer for the last name."
    I assumed that this was a typo error, i.e., that the idea is the opposite: if you pass a null pointer, then the function does not prompt for a last name because there is no space for the last name; if you pass a valid pointer to a string, then the function prompts for a last name because there is space for the last name.

    However, I checked the book and you're right: it does say "3. Modify the program you wrote for exercise 1 so that instead of always prompting the user for a last name, it does so only if the caller passes in a NULL pointer for the last name."

    This means that this is wrong:
    Code:
    if(pLname){
        cout << "Please enter your last name: ";
        getline(cin, *pLname);
    }
    This asks the user to enter the last name if pLname is not a null pointer. You want the user to enter the last name only if pLname is a null pointer. This means that you should write:
    Code:
    if (!pLname){
        cout << "Please enter your last name: ";
        getline(cin, *pLname);
    }
    But of course this is wrong too: since pLname is a null pointer, you cannot dereference it.

    What this means is that you need a string object for the last name:
    Code:
    string Lname;
    // ...
        cout << "Please enter your last name: ";
        getline(cin, Lname);
    Then you need to modify the way you create fullName to account for Lname.

    EDIT:
    Quote Originally Posted by KingFlippyNips
    I tried approaching the problem using references instead of pointers and it seems to work just fine.
    That's because the modification that you're trying to incorporate makes no sense when you're using references: there is no such thing as a null reference, so you cannot modify the program in that way. Therefore, you get what you did before you started trying to pass a null pointer as the second argument: it always works. Try passing a null pointer to your pointer version of the function before you modified it and it will likewise fail.
    Last edited by laserlight; 12-17-2018 at 10:18 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    SnoopFrogg KingFlippyNips's Avatar
    Join Date
    Sep 2016
    Posts
    33
    Quote Originally Posted by laserlight View Post

    This asks the user to enter the last name if pLname is not a null pointer. You want the user to enter the last name only if pLname is a null pointer. This means that you should write:
    Code:
    if (!pLname){
        cout << "Please enter your last name: ";
        getline(cin, *pLname);
    }
    But of course this is wrong too: since pLname is a null pointer, you cannot dereference it.

    What this means is that you need a string object for the last name:
    Code:
    string Lname;
    // ...
        cout << "Please enter your last name: ";
        getline(cin, Lname);
    Then you need to modify the way you create fullName to account for Lname.

    EDIT:

    That's because the modification that you're trying to incorporate makes no sense when you're using references: there is no such thing as a null reference, so you cannot modify the program in that way. Therefore, you get what you did before you started trying to pass a null pointer as the second argument: it always works. Try passing a null pointer to your pointer version of the function before you modified it and it will likewise fail.
    Thank you for clearing that up for me. With your help I was able to make my program work.
    Code:
    #include <iostream>
    #include <string>
     
    using namespace std;
     
    string name(string *pFname, string *pLname);
     
    int main(){
     
        string firstName;
        string *lastName= NULL;
        name(&firstName, lastName);
        return 0;
    }
     
    string name(string *pFname, string *pLname){
    
        string Lname;
    
        cout << "Please enter your first name: ";
        getline(cin, *pFname);
        if(!pLname){
            cout << "Please enter your last name: ";
            getline(cin, Lname);
        }
        string fullName = (*pFname) + " " + (Lname);
        cout << "Nice to meet you " << fullName;
        return fullName;
    }
    I still have one more question. Is there ever a time where one should use references over pointers? Also, you've helped me numerous times on this forum and I really appreciate it.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,067
    Quote Originally Posted by KingFlippyNips
    Thank you for clearing that up for me. With your help I was able to make my program work.
    You're welcome. However, note that your program actually makes no use of the last name pointer. Rather unfortunately, I think this exercise was either poorly designed or poorly worded: your answer is technically correct even though it is a bad solution, and I don't think we can change it into a good solution without changing the exercise entirely.

    Quote Originally Posted by KingFlippyNips
    Is there ever a time where one should use references over pointers?
    Generally, you should prefer to use reference parameters instead of pointer parameters if both are feasible as a pointer would need to checked if it is a null pointer. References are not feasible when the argument is optional, but in such a case you would be checking for the null pointer anyway. However, you might also use a pointer parameter even for a required argument for an out parameter (also called an output parameter) as explicitly requiring a pointer can be useful to indicate that the argument is to be modified, so this would require judgement to decide whether such an indication is useful or a hindrance.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 08-29-2015, 01:15 PM
  2. Replies: 43
    Last Post: 05-23-2013, 03:01 PM
  3. size of struct with pointers and function pointers
    By sdsjohnny in forum C Programming
    Replies: 3
    Last Post: 07-02-2010, 05:19 AM
  4. Storing function pointers in generic pointers
    By Boxknife in forum C Programming
    Replies: 6
    Last Post: 08-01-2009, 01:33 PM
  5. Pointers to objects -- passing and returning pointers
    By 1veedo in forum C++ Programming
    Replies: 4
    Last Post: 04-04-2008, 11:42 AM

Tags for this Thread