2

So I'm trying to get familiar with c++. And here is the task that is supposed to exercise usage of pointers. Here is how it goes:

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. It should prompt for the last name only if the caller passes in a NULL pointer for the last name.

I've tried a few versions. The one I'm stuck with now is:

#include <iostream>
#include <string>

using namespace std;


void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {
        cout << "Last name:";
        getline(cin, *p_last);
    }
}


int main() {

    string first;
    string *p_first = &first;
    string *p_last = NULL;

    getFullName(p_first, p_last);

    cout << *p_first << endl << *p_last << endl;
    return 0;
}

Well, it crashes. And I've tried to pass a reference to the 'last' and then pointing to it. But after exiting the function the pointer is NULL again.

1
  • Work on getting the interface for your function correct first, then worry about the implementation. Whoever generated the exercise needs to be a little bit clearer on what they want. Commented Jan 20, 2013 at 16:50

5 Answers 5

7

I think there is an error in the text of the exercise and it should read:

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. It should prompt for the last name only if the caller passes in a non-NULL pointer for the last name.

As it stands, your code causes undefined behaviour by dereferencing a null pointer

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {    /* <-- This test should be inverted */
        cout << "Last name:";
        /* Now, you get here only when p_last == NULL. On the next line, 
         * you dereference that null-pointer and try to read a string into 
         * non-existing memory: recipe for disaster.
         * With the condition inverted, you would only get here if you have 
         * a string to store the text in. */ 
        getline(cin, *p_last);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

It's most likely a typo. Thanks for clarification.
0

Don't use pointers, you don't need pointers for this. Just pass the parameters by reference:

void getFullName(string& p_first, string& p_last) 

However, the problem is you're dereferencing p_last which is NULL -> undefined behavior:

if (!p_last) {  //this evaluates to true, because p_last==NULL
    cout << "Last name:";
    getline(cin, *p_last);
}

6 Comments

I disagree, using reference parameters like this breaks the natural idiom of C++ (function parameters are passed by value). References should pretty much only be used as an efficiency measure (const references) or where the language requires them. Where you're expecting parameters to be altered pass-as-pointer is the better way to do it.
-1. The question is clearly about a homework exercise involving pointers. Recommending references does not help the OP in any way.
+1 from me because it is good advice nonetheless. @JackAidley I don't agree at all that the idiomatic way of passing something that should be modified if to pass a pointer to it.
@juanchopanza: Then the answer should also show how to pass an optional parameter using references.
@JackAidley: References are not about efficiency over pointers; they are even usually implemented as pointers. The big advantage they offer over pointers is that you don't have to test references against nullptr, 0 or NULL before using them. And, there is no such "natural idiom" in C++ that says "pointers are preferable"; that is not even an idiom!
|
0

Given that your question states you use an additional, I would write it as:

string getFullName()
{
    string first, last;
    cout << "First name:";
    getline(cin, first);
    cout << "Last name:";
    getline(cin, last);
    return first + last;  // note use of additional
}

Comments

0

The reason it is not working is because the call to getline takes a string reference (basic_string<>&) as the second argument, you're dereferencing a null pointer and passing it through. This is pretty much always going to give an error. You would need to new a fresh string to pass through to it, but this is a bad idea because it's pretty much guaranteed to lead to a memory leak since you've given yourself no way to pass it back.

Where you're passing a pointer expecting the value it points to to be altered and thus act as a return value you need to provide a valid pointer.

Comments

0

First of all, the assignment is faulty (if that is the complete assignment), or your interpretation of the assignemnt is faulty. Here's a version which will read last name, if p_last points to a string where it should be stored:

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (p_last) {
        cout << "Last name:";
        getline(cin, *p_last);
    }
}

Here's a version which use p_last as last name if it's not NULL, otherwise reads last name from user, and in both cases returns full name in p_first:

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    string lastname;
    if (!p_last) {
        cout << "Last name:";
        getline(cin, lastname);
    } else {
        lastname = *p_last;
    }
    *p_first += lastname;
}

Here's a version, which uses reference to pointer to alter p_last if it is NULL

void getFullName(string *p_first, string *&p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {
        p_last = new string;
        cout << "Last name:";
        getline(cin, *p_last);
    }
}

None of these match your assignment though.

Comments

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.