表达式:_BLOCK_TYPE_IS_VALID

时间:2014-05-24 19:01:13

标签: c++

我的字符串类有问题。在cin.get编译器显示此表达式后。我哪里出错了?

//Source.cpp
#include <iostream>
#include <string>
#include "str.h"
using namespace std;


int main()
{
        str S1 = "Hello, world!";
        str S2 = "LOL";
        str S3 = S2;
        cout << S3.cstr() << endl;
        cout << S1.size() << ": " << S1.cstr() << endl;
        cin.get();
}



//str.h
#ifndef STR_H
#define STR_H

class str
{
public:
        str(const char* = "");
        ~str();
        void operator=(const char*);
        void operator=(str);
        const char* cstr();
        int size();
private:
        void newString(const char*);
        char* charPtr;
        int Size;
};

#endif




//str.cpp
    #define _CRT_SECURE_NO_WARNINGS
    #include <cstring>
    using std::strlen;
    using std::strcpy;

    #include "str.h"

    str::str(const char* cstr)
    {
        newString(cstr);
    }
    str::~str()
    {
        delete[] charPtr;
    }
    const char* str::cstr()
    {
        return charPtr;
    }
    void str::newString(const char* cstr)
    {
        delete[] charPtr;
        Size = strlen(cstr);
        charPtr = new char[Size + 1];
        strcpy(charPtr, cstr);
    }
    void str::operator=(const char* cstr)
    {
        newString(cstr);
    }
    int str::size()
    {
        return Size;
    }

1 个答案:

答案 0 :(得分:1)

你没有服从rule of three。您有用户定义的析构函数和复制赋值运算符,但您尚未定义复制构造函数。编译器帮助</sarcasm>为您定义了一个。

在这一行:

str S3 = S2;

copy initialize S3。正如您可以从链接页面中的规则中看到的那样:

  

如果T是类类型而其他类型是cv非限定版本的T或从T派生的类,则检查T的构造函数,并通过重载决策选择最佳匹配。然后调用构造函数来初始化对象。

最佳匹配构造函数恰好是编译器添加的str(const str&);。默认的复制构造函数不会复制charPtr指向的数据,而只是复制指针。

当S2超出范围时,在cin.get();之后,它的析构函数删除了S2.charPtr。接下来,S3被销毁,它的析构函数尝试删除S3.charPtr,它具有与S2.charPtr相同的值,因此已被删除。 This has undefined behaviourQuick googling表示如果堆指针无效,则_BLOCK_TYPE_IS_VALID断言失败。我猜这可能是这种未定义行为的结果。

解决方案:实施复制构造函数str(const str&);,以便副本不共享数据。