简体   繁体   中英

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

I am practicing C++.

I implement the String class in two versions. 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.

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:

    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. You forgot the terminating NULL entry.

For issue // 2 , you are concatenating onto m_text before it is sized properly.

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. Specifying SIZE doesn't seem to be correct. 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 . 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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