这里我有一个创建字符串的函数,将它分配给字符串指针并返回它。我尝试返回一个常规字符串,它工作正常,但是当我集成指针和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_;
}
希望有人可以帮助我,谢谢!
答案 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);
现在处理引用,而不是处理指针。代码会更直接。