取消引用指针(并返回)的问题

Oni*_*ros 5 c++ string pointers runtime-error dereference

这里我有一个函数,它创建一个字符串,将它分配给一个字符串指针,然后返回它。我尝试返回一个常规字符串,它工作正常。但是当我集成指针并取消引用它们时,我的程序崩溃了。当我尝试调试它时,这是我得到的消息:

Unhandled exception at 0x00024cbf in Assignment 2.exe: 0xC0000005: Access violation reading location 0xcccccce4.

这是我的代码:

string* Recipe::getCookingTime()
// @intput: none
// @output: cooking time as a string
{
    string temp;
    string displayHrs;
    string displayMins;
    if( cookingTime_->numHours < 10 ) 
        displayHrs = intToString(0) + intToString(cookingTime_->numHours );
    else 
        displayHrs = intToString(cookingTime_->numHours );
    if( cookingTime_->numMinutes < 10 ) 
        displayMins = intToString(0) + intToString(cookingTime_->numMinutes);
    else 
        displayMins = intToString(cookingTime_->numMinutes);

    temp = "The time to cook the recipe is " + displayHrs + ":" + displayMins;
    *cTime_ = temp;
    return cTime_;
}
Run Code Online (Sandbox Code Playgroud)

dre*_*wag 4

问题是您取消引用 cTime_ 变量而没有首先实际分配内存。我不确定这是全局变量还是成员变量,但您需要首先使用“new”运算符来分配它的内存。因此,您将指向该变量(的地址)的指针返回给函数的调用者,但是一旦该函数退出,它就会删除“temp”变量,因此,您返回的指针将指向无效内存。

解决方案是使用“new”运算符:

string* Recipe::getCookingTime()
// @intput: none
// @output: cooking time as a string
{
    string displayHrs;
    string displayMins;
    if( cookingTime_->numHours < 10 ) 
        displayHrs = intToString(0) + intToString(cookingTime_->numHours );
    else 
        displayHrs = intToString(cookingTime_->numHours );
    if( cookingTime_->numMinutes < 10 ) 
        displayMins = intToString(0) + intToString(cookingTime_->numMinutes);
    else 
        displayMins = intToString(cookingTime_->numMinutes);

    if( NULL == cTime_ )
    {
        cTime_ = new string();
    }

    *cTime_ = "The time to cook the recipe is " + displayHrs + ":" + displayMins;
    return cTime_;
}
Run Code Online (Sandbox Code Playgroud)

但是,我必须警告您,这不是一个好的设计,因为您在这里分配内存并要求调用知道在使用完内存后必须释放它。更好的方法是让调用者分配变量,然后传入指针:

bool Recipe::getCookingTime( string* str )
// @intput: none
// @output: cooking time as a string
{
    if( NULL == str )
    {
        // Received invalid pointer
        return false;
    }
    string displayHrs;
    string displayMins;
    if( cookingTime_->numHours < 10 ) 
        displayHrs = intToString(0) + intToString(cookingTime_->numHours );
    else 
        displayHrs = intToString(cookingTime_->numHours );
    if( cookingTime_->numMinutes < 10 ) 
        displayMins = intToString(0) + intToString(cookingTime_->numMinutes);
    else 
        displayMins = intToString(cookingTime_->numMinutes);

    *str = "The time to cook the recipe is " + displayHrs + ":" + displayMins;
    return true;
}
Run Code Online (Sandbox Code Playgroud)

然后,当调用者想要使用该函数时,他们可以这样做:

cTime_ = new string();
getCookingTime( cTime_ );
Run Code Online (Sandbox Code Playgroud)

总结 这里要记住的重要一点是,在尝试分配指针所引用的内存之前,必须先分配该内存。此外,在函数内分配内存(使用 new 运算符)而不显式删除它通常是糟糕的设计。分配内存的人几乎总是释放它的人