1

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

主要:

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”时,内存地址会丢失。

感谢所有帮助,谢谢!

4

1 回答 1

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. 即使大小可能为零,您也可以在 data[0] 处推送一个 '\0'。

    我的字符串一个;a. 保留(0);// 碰撞?您写入了零长度数组的第一个字节。

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

  3. 您的 memcpy 使用“容量”而不是“大小”,因此可能会过度复制。

改为考虑:

// 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';可能是您的字符串被截断的原因。

于 2013-10-21T02:21:04.923 回答