检测到堆损坏

发布于 2024-10-27 02:07:39 字数 1199 浏览 3 评论 0原文

我的程序的输出唯一不正确的是有一个“!” “钓鱼”之后。我尝试过调试它,但从来没有“!”记忆中。

这是该行的输出

One more: gone down to the fishing! hole

这是 s6 和 s7 的创建

MyString s6("gone ");
MyString s7("fishing");

这是生成语句的行

cout << "One more: " << s6 + "down to the " + s7 + " hole" << endl << endl;

这是 <<运算符重载函数

ostream& operator<<(ostream& leftOp, const MyString& rightOp)
{
leftOp << rightOp.stringArray;

return leftOp;
}

这是 + 运算符重载函数

MyString MyString::operator+(const char* rightOp) const
{
    MyString result; // new object used to store result
    result.stringSize = stringSize + strlen(rightOp);
    // if the string does not fit in the array
    if( result.stringSize > result.stringCap )
    {
        delete[] result.stringArray;
        result.stringCap = ( stringSize + 15 ) & ~15;
        result.stringArray = new char[stringCap + 1];
    }
    strcpy(result.stringArray, stringArray);
    strcat(result.stringArray, rightOp);
    return result;
}

s7 在程序中的其他任何地方都没有调用,所以我认为不再需要显示代码。任何帮助将不胜感激。

The only thing that is incorrect about the output of my program, is that there is an '!' after 'fishing'. I have tried debugging it but there is never an '!' in memory.

Here is the output of this line

One more: gone down to the fishing! hole

Here is the creation of s6 and s7

MyString s6("gone ");
MyString s7("fishing");

Here is the line that produces the statement

cout << "One more: " << s6 + "down to the " + s7 + " hole" << endl << endl;

Here is the << operator overload function

ostream& operator<<(ostream& leftOp, const MyString& rightOp)
{
leftOp << rightOp.stringArray;

return leftOp;
}

Here is the + operator overload function

MyString MyString::operator+(const char* rightOp) const
{
    MyString result; // new object used to store result
    result.stringSize = stringSize + strlen(rightOp);
    // if the string does not fit in the array
    if( result.stringSize > result.stringCap )
    {
        delete[] result.stringArray;
        result.stringCap = ( stringSize + 15 ) & ~15;
        result.stringArray = new char[stringCap + 1];
    }
    strcpy(result.stringArray, stringArray);
    strcat(result.stringArray, rightOp);
    return result;
}

s7 is not called anywhere else in the program so I dont think there is anymore code that needs to be shown. Any help would be much appreciated.

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

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

发布评论

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

评论(4

泪意 2024-11-03 02:07:39

很难判断您的代码是否存在问题。
我会看看其他成员。 你遵守了3规则吗?

注意:

我想指出您违反了基本的面向对象规则。

除非有非常充分的理由,否则您不应该摆弄另一个对象的成员。
这里你的对象正在摆弄结果。

代码会更干净

MyString MyString::operator+(const char* rightOp) const
{
    MyString result(*this);   // make a copy of this.
    result += rightOp;        // Let result fiddle with its own members here.
    return result;
}

如果您将其编写为:编辑:

基于下面的评论,

三法则

基本上:如果你的对象拥有动态分配的内存(即它调用new/delete) 那么编译器生成的默认版本的方法就不能按你想要的方式工作;并且您应该定义自己的版本:

基本上:

* Copy Constructor
* Assignment Operator
* Destructor

* Not part of rule of 3, but you probably also need a normal constructor.

简单的事情是您可能已经有一个析构函数(否则就不会损坏),并且可以根据复制构造函数编写赋值运算符。因此,您所需要做的就是编写正确版本的复制构造函数,一切都应该可以正常工作。

/*
 * Assignment operator using Copy and swap Idiom.
 * Copy uses copy constructor (here done in pass by value)
 *
 * You then just swap the current content with the copy
 */
MyString& MyString::operator=(MyString rhs)
{
    (*this).swap(rhs);
    return *this;
}

It is hard to tell if the problem with your code is here.
I would look at the other members. Have you obeyed the rule of 3?

Note:

I would point out that you are breaking a fundamental OO rule.

You should not fiddle with the members of another object unless there is a very good reason.
Here your object is fiddling with result.

The code would be cleaner if you wrote it as:

MyString MyString::operator+(const char* rightOp) const
{
    MyString result(*this);   // make a copy of this.
    result += rightOp;        // Let result fiddle with its own members here.
    return result;
}

Edit:

based on comment below.

Rule of Three

Basically: If your object owns dynamically allocated memory (ie it calls new/delete) then the default version of the methods generated by the compiler do not work as you want; and you should define your own versions:

Basically:

* Copy Constructor
* Assignment Operator
* Destructor

* Not part of rule of 3, but you probably also need a normal constructor.

The easy thing is the you probably already have a destructor (otherwise there would not be corruption), and the assignment operator can be written in terms of the copy constructor. So all you need to do is write a correct version of the copy constructor and everything should work.

/*
 * Assignment operator using Copy and swap Idiom.
 * Copy uses copy constructor (here done in pass by value)
 *
 * You then just swap the current content with the copy
 */
MyString& MyString::operator=(MyString rhs)
{
    (*this).swap(rhs);
    return *this;
}
任性一次 2024-11-03 02:07:39

如果将 stringCap 分配给数组,您介意“\0”吗?存储字符串的 char* 必须是大小为 size-of-string + 1 的数组

问题可能出在连接两个 MyString 时。第二个字符串“钓鱼”可能具有太大的 stringSize 值。

而不是 result.stringCap = ( stringSize + 15 ) & ~15; 为什么不简单地写:

result.stringCap = result.stringSize + 1;

If you allocat stringCap to your array, do you mind about the '\0'? The char* storing the string must be an array of size size-of-string + 1

The problem is probably when you concat two MyString. The second string, fishing, may have a too big stringSize value.

And instead of result.stringCap = ( stringSize + 15 ) & ~15; why don't simply write:

result.stringCap = result.stringSize + 1;
夏见 2024-11-03 02:07:39

if( result.stringSize > result.stringCap ) 应为 if( result.stringSize >= result.stringCap ) 以允许 null 终止。您还需要重置 result.stringSize

if( result.stringSize > result.stringCap ) should be if( result.stringSize >= result.stringCap ) to allow for null termination. You also need to reset result.stringSize.

眼前雾蒙蒙 2024-11-03 02:07:39

正常情况下你没有分配stringArray,太大的情况下你没有重置stringSize,strncpy更安全:

MyString MyString::operator+(const char* rightOp) const
{
    MyString result; // new object used to store result
    result.stringSize = stringSize + strlen(rightOp);
    // if the string does not fit in the array
    if( result.stringSize > result.stringCap )
    {
        delete[] result.stringArray;
        result.stringCap = ( stringSize + 15 ) & ~15;
        // don't allocate here
        result.stringSize = stringCap;
    }

    // always allocate for the new string
    result.stringArray = new char[result.stringSize + 1];

    strncpy(result.stringArray, stringArray, result.stringSize);
    strncat(result.stringArray, rightOp, strlen(rightOp) + 1);
    return result;
}

编辑:好的,忽略那。我对 MyString 类做了一些假设,但事实显然并非如此。所以,我现在可以指出的是:

if( result.stringSize > result.stringCap )
{
    delete[] result.stringArray;
    result.stringCap = ( stringSize + 15 ) & ~15;
    result.stringArray = new char[stringCap + 1]; // WRONG stringCap!
    result.stringArray = new char[result.stringCap + 1]; // right stringCap
}

您可以尝试简化事情,以缩小问题范围:

cout << "One more: " << s6 + "down to the " << s7 + " hole" << endl << endl;

也许问题出在 operator+(const MyString&) 而不是 operator+(const char *)?

You didn't allocate stringArray in the normal case, and you didn't reset the stringSize in the too-large case, and strncpy is safer:

MyString MyString::operator+(const char* rightOp) const
{
    MyString result; // new object used to store result
    result.stringSize = stringSize + strlen(rightOp);
    // if the string does not fit in the array
    if( result.stringSize > result.stringCap )
    {
        delete[] result.stringArray;
        result.stringCap = ( stringSize + 15 ) & ~15;
        // don't allocate here
        result.stringSize = stringCap;
    }

    // always allocate for the new string
    result.stringArray = new char[result.stringSize + 1];

    strncpy(result.stringArray, stringArray, result.stringSize);
    strncat(result.stringArray, rightOp, strlen(rightOp) + 1);
    return result;
}

EDIT: Ok, disregard that. I assumed certain things about the MyString class which are apparently not the case. So, here's what I can point out now:

if( result.stringSize > result.stringCap )
{
    delete[] result.stringArray;
    result.stringCap = ( stringSize + 15 ) & ~15;
    result.stringArray = new char[stringCap + 1]; // WRONG stringCap!
    result.stringArray = new char[result.stringCap + 1]; // right stringCap
}

And you can try simplifying things, to narrow down the problem:

cout << "One more: " << s6 + "down to the " << s7 + " hole" << endl << endl;

maybe the issue is in operator+(const MyString&) instead of operator+(const char*)?

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