【问题标题】:C++ merge 2 wchar_t*C++ 合并 2 wchar_t*
【发布时间】:2019-06-14 09:38:12
【问题描述】:

我有一个有趣的问题,我不知道为什么。

inline void mergeWChar(wchar_t*& dest, const wchar_t* source) {
    if (dest == nullptr) {
        dest = const_cast<wchar_t*>(source);
        return;
    }
    int size = wcslen(dest);
    wcscat_s(dest, size, source);
}
inline void test() {
    wchar_t* msg = nullptr;
    wchar_t* t = L"BLA.BLA.BLA";
    mergeWChar(msg, L"Ts is jut a phrase in order to test my function");
    mergeWChar(msg, t);
}

我正在尝试使用 wcscat_s 函数创建一个将合并更严格的 2 wchar_t* 的函数,但由于某种原因无法正常工作,并且我收到了此错误消息。

在 ConsoleApplication1.exe 中的 0x5D8C3A18 (ucrtbased.dll) 处引发异常:0xC0000005:访问冲突写入位置 0x0082DD60。

另外,我已经检查了这两个问题,并没有真正帮助我。

wcscat_s problem

wcscat_s function - buffer error

我不能做什么

我正在使用一些遗留代码,我可以使用以下代码:

  1. 字符串
  2. to_wstring
  3. wchar_t var[size]

【问题讨论】:

  • wchar_t* t = L"BLA.BLA.BLA"; 在我这边无法编译。 “无法从 'const wchar_t [12]' 转换为 'wchar_t *'”
  • 这很糟糕,dest = const_cast&lt;wchar_t*&gt;(source);。你承诺你不会修改source,但是你给了调用者一个指向它的非常量指针。谁或什么应该为级联输出分配内存?

标签: c++ visual-c++


【解决方案1】:

这里:

mergeWChar(msg, t);

msg 指向字符串文字L"Ts is jut a phrase in order to test my function"。您不能修改字符串文字。

你想要这个:

inline void mergeWChar(wchar_t*& dest, const wchar_t* source) {
  if (dest == nullptr) {
    dest = const_cast<wchar_t*>(source);
    return;
  }

  wchar_t *newdest = (wchar_t*)malloc((wcslen(dest) + wcslen(source) + 1) * sizeof *newdest);
  wcscpy(newdest, dest);      // the *_s functions are useless here
  wcscat(newdest, source);    // as you know that newdest point to
                              // a long enough buffer
  dest = newdest;
}

免责声明:为简洁起见,此处未进行错误检查。

问题的根源在于 mergeWChar 函数的糟糕设计和 const_cast&lt;wchar_t*&gt; 的可疑使用,它基本上允许您将指向常量字符串的指针分配给普通指针,然后允许您修改它最终失败的持续记忆。

但是这种设计存在一个问题:您无法释放分配的内存,因为dest 指针不一定是通过malloc 获得的指针。因此,以下设计是更好的 IMO:

inline void mergeWChar(wchar_t*& dest, const wchar_t* source) {
  int size = (dest ? wcslen(dest) : 0) + wcslen(source) + 1;
  wchar_t *newdest = (wchar_t*)malloc(size * sizeof *newdest);
  if (dest)
    wcscpy(newdest, dest);
  else
    newdest[0] = 0;
  wcscat(newdest, source);
  dest = newdest;
}

这样就没有丑陋的强制转换,也没有指向常量内存的非 const 指针的风险,并且您可以确保无论如何都可以释放 mergeWChar 修改的指针。代价是您需要更多内存。

使用示例:

...
wchar_t* msg = nullptr;
wchar_t* t = L"BLA.BLA.BLA";
mergeWChar(msg, L"Ts is jut a phrase in order to test my function");
mergeWChar(msg, t);
...
free(msg);
...

【讨论】:

  • 您的想法很好,一切正常,但有一个例外。您正在那里使用 malloc,您不应该删除那个或当前的 dest?因为到目前为止我可以看到有内存泄漏,不是吗?
  • @Mircea 是的,你当然需要注意这一点,因此无论如何你都应该使用第二个版本。我编辑了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-09
  • 1970-01-01
相关资源
最近更新 更多