【问题标题】:Cannot create new wchar_t *无法创建新的 wchar_t *
【发布时间】:2012-10-30 15:45:02
【问题描述】:

我有这个运算符重载器。 我的程序在创建新的wchar_t 数组时崩溃。

myObject &operator += (const myObject &s) {
    wchar_t *cat = wcscat(data, s.data);
    int len = wcslen(cat);
    wchar_t *test = new wchar_t[len + 1]; //this is killing!
    wcscpy(test, cat);

    delete data;
    data = test;

    return *this;
}

有人知道发生了什么吗?

编辑完整的类定义

class myObject
{
    private:
        wchar_t *data;
    public:
        myObject() { data = 0; }
        ~myObject() { delete data; }

        myObject &operator += (const myObject &s) {
            wchar_t *cat = wcscat(data, s.data);
            int len = wcslen(cat);
            wchar_t *test = new wchar_t[len + 1];
            wcscpy(test, cat);

            delete data;
            data = test;

            return *this;
        }
};

【问题讨论】:

  • “这是杀戮”是什么意思?
  • 让班级持有std::wstring,难道不能省去很多麻烦吗?
  • data 是否大到足以容纳最后的s.data?您还使用错误的delete 调用了UB。
  • 该行导致程序崩溃。
  • @chris 我的程序无法通过创建新数组。所以它与对象没有任何关系吧?

标签: c++ new-operator operator-keyword wchar-t


【解决方案1】:

正如 Dietmar 所说(但更详细地说可能在幕后发生了什么):

1) 调用wcscat(data, s.data) 已超出data 指向的缓冲区的末尾。如果它没有溢出,那么你就不需要分配一个新的缓冲区,因为现有的缓冲区已经足够大了。我希望它不够足够大。

2) 由于缓冲区溢出,内存分配器使用的数据结构被丢弃。当您尝试分配内存时,这会导致崩溃。当您释放内存时,它也很容易导致崩溃,或者根本不会崩溃。

【讨论】:

    【解决方案2】:

    这段代码至少包含两个相当明显的问题:

    1. 您显然使用new wchar_t[n] 分配数据,但您使用delete p 而不是使用delete[] p 释放它。
    2. 问题的可能原因是您将两个字符串连接到一个字符串的内存中,然后分配了足够的内存来复制数据。

    你可能想要更多类似的东西:

    myObject &operator += (const myObject &s) {
        size_t len = wcslen(this->data) + wcslen(s.data);
        std::unique_ptr<wchar_t[]> tmp(new wchar_t[len + 1]);
        wcscpy(tmp.get(), this->data);
        wcscat(tmp.get(), s.data);
        delete[] this->data;
        this->data = tmp.release();
        return *this;
    }
    

    实际上,我认为您想使用std::wstring:这个类已经提供了逻辑,无论如何可能以更有效的形式。

    【讨论】:

    • “可能以更有效的形式” - 一方面,它不必用wcslen 测量字符串的长度,或者像wcscat 那样跳过目标字符串。
    • 感谢您的回答。我会试试看。我不使用 wstring 的原因是我正在尝试学习使用这些数组,所以我知道发生了什么
    • @HansElsen 了解幕后发生的事情是个好主意。一旦你学会了这一点,别忘了回到简单的方法。
    • 谢谢大家,这个解决方案有效。我还制作了一个更基本的解决方案,使用 2 个 for 循环来填充新数组。但是现在问题很清楚了。从现在开始我可以使用 wstrings 了哈哈。
    • 你不应该使用任何for-loops 来做这样的事情,不过!理想情况下,您现在可以将它们有多少个字符串起来,并将迭代器(可能是wchar_t const)暴露给它们的元素。然后填充新数组将如下所示:std::copy(s.begin(), s.end(), std::copy(this-&gt;begin(), this.end(), tmp.get()));
    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 2014-07-25
    • 1970-01-01
    • 2019-09-10
    相关资源
    最近更新 更多