Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 取消引用指针(并返回它)的问题_C++_Pointers_String_Runtime Error_Dereference - Fatal编程技术网

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

C++ 取消引用指针(并返回它)的问题,c++,pointers,string,runtime-error,dereference,C++,Pointers,String,Runtime Error,Dereference,这里我有一个函数,它创建一个字符串,将它分配给一个字符串指针,然后返回它。我试着返回一个常规字符串,结果很好。但是当我集成指针并取消引用它们时,我的程序崩溃了。当我尝试调试它时,我得到的消息如下: 分配2.exe中0x00024cbf处未处理的异常:0xC000005:访问冲突读取位置0xCCCCCC4 这是我的密码: string* Recipe::getCookingTime() // @intput: none // @output: cooking time as a string {

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

分配2.exe中0x00024cbf处未处理的异常:0xC000005:访问冲突读取位置0xCCCCCC4

这是我的密码:

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_;
}
string*配方::getCookingTime()
//@intput:none
//@output:cooking time作为字符串
{
字符串温度;
字符串显示小时数;
字符串显示分钟;
如果(烹饪时间->numHours<10)
displayHrs=intToString(0)+intToString(烹饪时间->numHours);
其他的
displayHrs=intToString(烹饪时间->numHours);
如果(烹饪时间->数值<10)
displayMins=intToString(0)+intToString(cookingTime->numMinutes);
其他的
displayMins=intToString(烹饪时间->numMinutes);
temp=“烹饪食谱的时间为“+displayHrs+”:“+displayMins;
*时间=温度;
返回cTime;
}
您似乎还没有为
cTime\uu
分配内存

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

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

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

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

解决方案是使用“新”操作符:

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_;
}
摘要
这里需要记住的重要一点是,在尝试分配给指针之前,必须分配指针引用的内存。此外,在函数中分配内存(使用新运算符)而不显式删除内存通常是不好的设计分配内存的人几乎总是释放内存的人

我只关注问题的地址,而不是代码中的任何其他地方。首先,我不认为您发布了完整的代码,因为根据您发布的内容,我看不到该方法中定义了cTime_uu的位置,因此您的代码甚至不会编译。其次,假设您将cTime_uu定义为指向字符串的指针,并将该指针分配给字符串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;
}

现在不再处理指针,而是处理引用。代码将更简单。

不这样做的唯一原因是防止复制发生的返回字符串。(这只在嵌入式环境、真正密集的应用程序或调用相对频繁的函数中才是一个真正的问题)。@drewag:现在大多数编译器实现RVO:。。。此外,如果您分配内存并返回,并且在处理完之后,当您重新阅读问题并意识到原始答案是错误的时候,释放内存,但您认为这仍然是一个好建议,最好的做法是用
包围它,这样它就被划掉了,但仍然可读。您的第一个代码示例也是一场灾难<代码>*字符串=…<代码>字符串是一种类型!关于编辑的观点很好,我会修复它,但我不会取消引用类型,即指向传入的字符串类型的指针。我们都可以看到您的编辑历史记录,因此,确认拼写错误并修复它比否认注释中提出的问题看起来要好得多。我不打算忽略一个问题,我只想给其他读过它的人一个更清楚的答案。你也可以更尊重一点。我是论坛的新手,仍然在学习标准实践。我所要做的就是学习和帮助别人。不,
cTime\uucode>不是指向
temp
temp
被复制到wherever
cTime\uu
点(根据错误消息,显然没有任何地方)。您这样做很困难,没有充分的理由<代码>字符串s=getCookingTime()
同样高效,如果按值返回字符串,那么可能也会执行同样的操作。相信你的编译器!非常感谢您的回复,现在我修复了它,它开始工作了。我忘了分配内存:S。我知道这样做比较容易,但我必须编写一个符合特定规格的程序。实现这一功能就是其中之一。
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_ );
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;
}
string s;
getCookingTime(s);