gpt4 book ai didi

c++ - 使用 wcsncpy_s 复制字符串时缓冲区太小

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:25:47 27 4
gpt4 key购买 nike

这段 C++ 代码有点蹩脚,但我需要维护它。我似乎无法弄清楚“缓冲区太小”的问题。我正在使用 Visual Studio 2010。我将根据我在调试器中看到的值提出重现所需的最少代码。抱歉,我不会测试实际的片段本身。另外,由于我的系统剪贴板在我调试时“很忙”,我不能只是复制和粘贴,所以一些错误可能会在某处蔓延,但我会仔细检查一些东西。相信我,您不想看到整个函数 - 它太长了,没有任何意义:)

来自 tchar.h

#define _tcsncpy_s wcsncpy_s

来自 afxstr.h:

typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;

来自 WinNT.h:

typedef WCHAR TCHAR, *PTCHAR;

哦,伙计,这些宏似乎永远不会结束。我会在这里停下来。最后,来自 myfile.cpp:

CString str; // Actually a function parameter with value "07/02/2010"
DWORD nIndex = 10;
DWORD nLast = 0;
LPCTSTR psz = (LPCTSTR) str; // Debugger says that it also gets "07/02/2010".

CString s;
_tcsncpy_s(
s.GetBuffer((int) (nIndex - nLast + 1)), // I added the " + 1" part hoping to fix a bug, but that changed nothing
nIndex - nLast,
psz + nLast,
(size_t) (nIndex - nLast)
);

有了这个,我命中了一个断言,调试器打开了 tcsncpy_s.inl,末尾有以下代码:

  53    ...
54 if (available == 0)
55 {
56 if (_COUNT == _TRUNCATE)
57 {
58 _DEST[_SIZE - 1] = 0;
59 _RETURN_TRUNCATE;
60 }
61 RESET_STRING(_DEST, _SIZE);
=>62 _RETURN_BUFFER_TOO_SMALL(_DEST, _SIZE);
63 }
64 _FILL_STRING(_DEST, _SIZE, _SIZE - available + 1);
65 _RETURN_NO_ERROR;
66 }
67
68

调试器指向第 62 行:_RETURN_BUFFER_TOO_SMALL。不幸的是,我无法在 tcsncpy_s.inl 中查看事物的值。也许有经验的编码员可以告诉我这里发生了什么?我相信(也许是错误的)这段代码已经很老了,而且在编写时并没有考虑到 Unicode。解决这个问题的最佳方法是什么,它粘在旧的 N 蹩脚枪上(请不要使用 C++0X 技巧或其他花哨的东西)——我只想在枪伤上贴上补丁。

最佳答案

strncpy_s 的第四个参数是要从源缓冲区复制的字符数,它不考虑终止 null - 也就是说,在实践中,如果源缓冲区包含一个字符串有 (nIndex - nLast) 或更多字符,则 (nIndex - nLast) 将被复制,然后将附加一个空字符.因此,目标缓冲区必须准备好接受 (nIndex - nLast + 1) 个字符,以解决该空值。

现在您的 +1 似乎是这样做的,但您还应该在 strncpy_s 的第二个参数中反射(reflect)它,它告诉它缓冲区有多大。将其更改为 (nIndex - nLast + 1),它应该可以工作。

关于c++ - 使用 wcsncpy_s 复制字符串时缓冲区太小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3215310/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com