C ++合并2 wchar_t *

时间:2019-06-14 09:38:12

标签: c++ visual-c++

我有一个有趣的问题,我不确定为什么。

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. wstring
  2. to_wstring
  3. wchar_t var [size] <-无效。

1 个答案:

答案 0 :(得分: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<wchar_t*>的可疑使用,这基本上使您可以将指向常量字符串的指针分配给普通指针,然后再将其分配给普通指针您需要修改该常量内存,而该内存最终会失败。

但是这种设计存在一个问题:您不能释放分配的内存,因为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);
...