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

发布于 2024-10-24 05:27:39 字数 908 浏览 2 评论 0原文

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

Assignment 2.exe 中 0x00024cbf 处出现未处理的异常: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_;
}

Here I have a function that creates a string, assigns it to a string pointer, and returns it. I tried returning a regular string and it worked fine. But then when when I integrated the pointers and de-referenced them, my program crashed. When I tried to debug it, this is the message I got:

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

Here's my code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沒落の蓅哖 2024-10-31 05:27:39

问题是您取消引用 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 运算符)而不显式删除它通常是糟糕的设计。 分配内存的人几乎总是释放它的人

The problem is that you are dereferencing the cTime_ variable without actually allocating the memory first. I am not sure if that is a global variable or a member variable but you need to use the "new" operator first to allocate it's memory. So you return the pointer to (address of) this variable back to the caller of the function, but as soon as this function exits, it is deleting the "temp" variable and therefore, the pointer you returned will be pointing at invalid memory.

The solution would be to use the "new" operator:

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

However, I have to warn you that this is not good design because here you are allocating memory and require that the call knows they have to free it when they are done with it. A preferable way to do it would be to have the caller allocate the variable and then pass in the pointer:

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

Then when the caller wants to use the function they can do this:

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

Summary
The important thing to remember here is that you must allocate memory the a pointer is referencing before trying to assign to it. Also, it is generally bad design to allocate memory (using the new operator) within a function and not explicitly delete it. Whoever allocates memory should almost always be the one to free it

半夏半凉 2024-10-31 05:27:39
*cTime_ = temp;

您似乎尚未为 cTime_ 分配内存。

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

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

注意,返回类型的类型从 std::string* 更改为 std: :字符串

*cTime_ = temp;

It seems you've not allocated memory for cTime_.

I'm wondering why you're returning pointer to std::string. Why don't you simply return std::string as shown below:

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

Note that the type of return type is changed from std::string* to std::string.

世界等同你 2024-10-31 05:27:39

我将只关注您的问题所在的位置,而不是代码中的其他任何地方。首先,我认为您没有发布完整的代码,因为根据您发布的内容,我看不到 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);

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

I'll just focus on where your question addresses and not anywhere else in your code. First, I don't think you posted your complete code, because with what you posted, I don't see where cTime_ is defined in that method, so your code won't even compile. Second, assume you define cTime_ as a pointer to a string, and assign that pointer to a the memory occupied by the string temp. When that method exits, temp goes out of scope, now cTime_ no longer points to a valid memory location, thus you get the access violation. You might consider something like this:

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

Then to call getCookingTime():

string s;
getCookingTime(s);

Instead of dealing with pointer, you would now deal with reference. The code would be more straightforward.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文