简体   繁体   English

在C ++中取消引用NULL指针

[英]Dereference NULL pointer in C++

So I'm trying to get familiar with c++. 因此,我试图熟悉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. 仅当调用者传递NULL指针作为姓氏时,才应提示输入姓氏。

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. 但是退出函数后,指针再次为NULL。

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. 仅当调用者传递用于姓氏的非NULL指针时,才应提示输入姓氏。

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);
    }
}

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: 然而,问题是你提领p_lastNULL - >未定义行为:

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

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
}

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. 它无法工作的原因是因为对getline的调用采用字符串引用( basic_string<>& )作为第二个参数,您将取消引用空指针并将其传递给它。 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. 你需要new一个新的字符串来传递给它,但这是一个坏主意,因为它几乎可以保证导致内存泄漏,因为你没有办法将它传回去。

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. 在传递指针时,期望它指向的值被更改,从而作为返回值,您需要提供有效的指针。

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: 如果p_last指向应该存储该字符串的字符串,则该版本将读取姓氏:

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 : 这是一个使用p_last作为姓氏的版本,如果它不是NULL,否则从用户读取姓氏,并且在两种情况下都返回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 这是一个版本,如果它是NULL,则使用对指针的引用来改变p_last

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. 这些都不符合您的任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM