简体   繁体   English

C ++中的错误分配异常,因为为char *分配了内存

[英]bad allocation exception in c++ as allocating memory for char*

I am practicing C++. 我正在练习C ++。

I implement the String class in two versions. 我在两个版本中实现了String类。 in the first version the text is saved in a array. 在第一个版本中,文本保存在数组中。 in the second version, the text is saved in a dynamic allocation memory. 在第二版中,文本被保存在动态分配存储器中。 the second version inherits the first. 第二个版本继承第一个。

the first version works OK. 第一个版本工作正常。 in the second version, in the first line of the concat function, i get a bad allocation exception. 在第二个版本的concat函数的第一行中,我得到了一个错误的分配异常。

this is the code: 这是代码:

        #include<iostream>
    #include<string>
    using namespace std;

    class String{

    protected:
        enum{SIZE=256};
        void setLen(const int length)
        {
            m_len = length;
        }
    private:
        int m_len;
        char m_text [SIZE];

    public:

        String()
        {
            m_len = 0;
            strcpy_s (m_text, 1, "");
        }
        String(const char* text)
        {
            m_len = strlen(text);
            strcpy_s (m_text, strlen(text) + 1,  text);
        }
        const char* get() const
        {
            return m_text;
        }
        virtual void set(char* text)
        {
            strcpy_s (m_text, strlen(text) + 1, text);
        }
        int getLen() const
        {
            return m_len;
        }
        virtual void concat(const String &s)
        {
            strcat_s(m_text, strlen(m_text) + strlen(s.get()) + 1, s.m_text);
        }
        bool equal(const String &s)const
        {
            return strcmp(s.m_text, m_text);
        }
        bool operator ==(const String &s)const
        {
            return strcmp(s.m_text, m_text);
        }
        virtual void print()const
        {
            cout<<m_text;
        }


    };

    class PointString :public String {
        char* m_text;
    public:
        PointString()
        {
            setLen(0);
            m_text = new char[1];
            strcpy_s(m_text, 1,"");
        }
        PointString(const char* text)
        {
            setLen(strlen(text));
            m_text = new char[strlen(text)+1];
            strcpy_s(m_text, strlen(text)+1 ,text);
        }
        void set(char* text)
        {
            delete [] m_text;
            setLen(strlen(text));
            m_text = new char[strlen(text)+1];
        }
        void concat(const String &s)
        {
            char *temp = new char[strlen(m_text) + strlen(s.get())];
            strcpy_s(temp, SIZE, m_text);
            strcat_s(m_text,strlen(m_text) + strlen(s.get()) + 1, s.get());
            delete [] m_text;
            m_text = temp;
        }
        void print()const
        {
            cout<<m_text<<endl;
        }
    };

void main()
{
    PointString str("1234");
    str.print();
    str.concat("8901");
    str.print();
    system("pause");
}

The issue is this in your concat call: 问题是在您的concat通话中:

    char *temp = new char[strlen(m_text) + strlen(s.get())]; // 1
    strcpy_s(temp, SIZE, m_text);  
    strcat_s(m_text, strlen(m_text) + strlen(s.get()) + 1, s.get());  // 2
    delete[] m_text;
    m_text = temp;

For issue // 1 , you did not allocate enough space for the string. 对于问题// 1 ,您没有为字符串分配足够的空间。 You forgot the terminating NULL entry. 您忘记了终止NULL条目。

For issue // 2 , you are concatenating onto m_text before it is sized properly. 对于问题// 2 ,您需要在适当调整大小之前将其串联到m_text

Using standard string functions, the changes below cause no issues: 使用标准的字符串函数,以下更改不会引起问题:

    char *temp = new char[strlen(m_text) + strlen(s.get()) + 1];
    strcpy(temp, m_text);
    strcat(temp, s.get());
    delete[] m_text;
    m_text = temp;

Using the Microsoft safe string functions, you should save the length of the new string in a variable and use it in each call. 使用Microsoft安全字符串函数,应将新字符串的长度保存在变量中,并在每次调用中使用它。 Specifying SIZE doesn't seem to be correct. 指定SIZE似乎不正确。 Here is what works for me: 这对我有用:

void concat(const String &s)
{
    size_t sz = strlen(m_text) + strlen(s.get()) + 1;
    char *temp = new char[sz];
    strcpy_s(temp, sz, m_text);
    strcat_s(temp, sz, s.get());
    delete[] m_text;
    m_text = temp;
}

There are other issues with your code. 您的代码还有其他问题。 One is the lack of a destructor, thus you have memory leaks whenever you create a PointString . 一种是缺少析构函数,因此每次创建PointString时都会发生内存泄漏。 The other issue is that copying and assigning a PointString to another PointString will not work correctly due to a lack of a user-defined copy constructor and assignment operator. 另一个问题是,由于缺少用户定义的复制构造函数和赋值运算符,因此无法将PointString复制并分配给另一个PointString正常工作。

Please read up on the above topics, as a string class that cannot make copies of themselves is practically not worth using (if you were going to use it), on top of not being usable at all due to the memory leaks present (no destructor). 请仔细阅读上述主题,因为不能复制自己的副本的字符串类实际上不值得使用(如果您打算使用),并且由于存在内存泄漏(没有析构函数)根本无法使用)。

If you remove yourself from the "homework" phase, the std::string class does all of the work you're doing now, except more safe and efficient. 如果您将自己从“家庭作业”阶段中删除,则std::string类将执行您现在正在执行的所有工作,除了更加安全和有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM