繁体   English   中英

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

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

我正在练习C ++。

我在两个版本中实现了String类。 在第一个版本中,文本保存在数组中。 在第二版中,文本被保存在动态分配存储器中。 第二个版本继承第一个。

第一个版本工作正常。 在第二个版本的concat函数的第一行中,我得到了一个错误的分配异常。

这是代码:

        #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");
}

问题是在您的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;

对于问题// 1 ,您没有为字符串分配足够的空间。 您忘记了终止NULL条目。

对于问题// 2 ,您需要在适当调整大小之前将其串联到m_text

使用标准的字符串函数,以下更改不会引起问题:

    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;

使用Microsoft安全字符串函数,应将新字符串的长度保存在变量中,并在每次调用中使用它。 指定SIZE似乎不正确。 这对我有用:

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

您的代码还有其他问题。 一种是缺少析构函数,因此每次创建PointString时都会发生内存泄漏。 另一个问题是,由于缺少用户定义的复制构造函数和赋值运算符,因此无法将PointString复制并分配给另一个PointString正常工作。

请仔细阅读上述主题,因为不能复制自己的副本的字符串类实际上不值得使用(如果您打算使用),并且由于存在内存泄漏(没有析构函数)根本无法使用)。

如果您将自己从“家庭作业”阶段中删除,则std::string类将执行您现在正在执行的所有工作,除了更加安全和有效。

暂无
暂无

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

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