解除引用指针(并返回指针)的问题

时间:2011-03-19 03:47:28

标签: c++ pointers string runtime-error dereference

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

分配中的0x00024cbf处的未处理异常2.exe:0xC0000005:访问冲突读取位置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_;
}

希望有人可以帮助我,谢谢!

3 个答案:

答案 0 :(得分:3)

问题是你是在取消引用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_;
}

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

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

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

cTime_ = new string();
getCookingTime( cTime_ );

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

答案 1 :(得分:2)

*cTime_ = temp;

您似乎没有为cTime_分配内存。

我想知道你为什么要返回指向std::string的指针。为什么不简单地返回std::string,如下所示:

std::string Recipe::getCookingTime()
{
   //your same code
   return temp; //this is fine!
}

请注意,返回类型的类型已从std::string*更改为std::string

答案 2 :(得分:-2)

我只关注您的问题所针对的地方,而不是代码中的其他任何地方。首先,我不认为你发布了完整的代码,因为你发布的内容,我没有看到在该方法中定义cTime_的位置,所以你的代码甚至不会编译。其次,假设您将cTime_定义为指向字符串的指针,并将该指针指定给字符串temp占用的内存。当该方法退出时,temp超出范围,现在cTime_不再指向有效的内存位置,因此您将获得访问冲突。你可能会考虑这样的事情:

void Recipe::getCookingTime( string& str )
{
    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;
}

然后调用getCookingTime():

string s;
getCookingTime(s);

现在处理引用,而不是处理指针。代码会更直接。