C ++ My String类:指针不起作用

时间:2013-10-21 01:58:03

标签: c++ pointers memory-management c++11 operator-overloading

我在c ++ 11中构建自己的字符串类,我遇到了内存问题。

在main中:

MyString str1;     //Works ok, constructor creates empty char array.
const char* pointer1 = str1.c_str(); //Return the pointer to the array.
str1.Reserve(5); 

// Now, when I use the Reverse method in string1, Pointer1 is 
// pointing to the old memory address.

如何更改str1中的数组数据,但更改为内存地址?

另外,我如何解决这个问题:

pointer1 == str1.c_str();

预约方法:

void reserve(int res)
{
    capacity = NewSize(size + res,0 , capacity); //Method to find the best cap.

    char* oldData = data;

    data = new char[capacity];
    memcpy(data, oldData, capacity);
    oldData = data;
    //delete[] data;

    data[(size)] = '\0';
}

这将返回所有正确的数据,但是当我执行“oldData = data”时,内存地址将丢失。

感谢所有人的帮助,谢谢!

1 个答案:

答案 0 :(得分:2)

我认为你要问的是,是否有办法从字符串类中获取返回值,该值始终指向当前字符串数组。有很多方法可以做到这一点,但通常这表明设计/实施不好。

更常见的方法是建议API用户c_str()的结果被对象的任何后续修改无效:不要保留指针,只需再次调用c_str()。

两个明显的选项是:a)指向指针的指针,非常危险,因为现在你的类外面的人可以调整它,b)提供一个封装指针类的封装类,不需要修改。

template<typename T>
struct ReadOnlyPointer {
    T* m_ptr;
    ... operator * ...
    ... operator -> ...
    ... operator T ...
};

ReadOnlyPointer<const char*> pointer = str1.pointer();

“保留”功能似乎至少存在一些问题。

  1. 即使大小可能为零,也会在数据[0]处按'\ 0'。

    MyString a; a.reserve(0); //崩溃?你写了一个零长度数组的第一个字节。

  2. 将数据从oldData复制到数据后,出于某种原因,您将'data'的值分配给'oldData',然后再也不再使用'oldData' - 这是内存泄漏。

    < / LI>
  3. 您的memcpy使用'capacity'而不是'size',因此可能会过度复制。

  4. 改为考虑:

    // ensure we have an additional 'res' bytes.
    // caution: unlike stl and boost reserve, these are
    // additional bytes, not total bytes.
    void reserve(int res)
    {
        int newCapacity = NewSize(m_size + res, 0, m_capacity); //Method to find the best cap.
        if(newCapacity <= m_capacity)
            return;
    
        char* newData = new char[newCapacity];
        memcpy(newData, m_data, m_size);
        delete[] m_data;        // release the old allocation
        m_data = newData;
        m_capacity = newCapacity;
    }
    

    如果您没有更改代码中其他位置的大小值,额外的data[(size)] = '\0';可能会导致字符串被截断。