Reputation: 38670
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.
Upvotes: 2
Views: 2538
Reputation: 62777
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.
Upvotes: 0
Reputation: 15768
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);
}
}
Upvotes: 7
Reputation: 20107
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.
Upvotes: 0
Reputation: 38825
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
}
Upvotes: 0
Reputation: 258568
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);
}
Upvotes: 0