这是几年前我认为微不足道的事情。。。我已经有一段时间没有涉足C或C++了,现在我有一个问题导致了偏头痛。
我收到以下代码的错误:
CompressFile::CompressFile(wchar_t *WorkingDirectory, wchar_t *File)
{
int bzipError = BZ_OK;
wprintf(L"Attempting to compress %s%sn", WorkingDirectory, File);
wchar_t FileRawInput[MAX_PATH];
wcsncpy(FileRawInput, WorkingDirectory, sizeof(FileRawInput));
wcsncat(FileRawInput, File, sizeof(FileRawInput));
wchar_t bzipCompressedOutput[MAX_PATH];
wcsncpy(bzipCompressedOutput, FileRawInput, sizeof(bzipCompressedOutput));
wcscat(bzipCompressedOutput, L".bz2");
wprintf(L"Output of string bzip: %sn", bzipCompressedOutput);
wprintf(L"Output of string raw: %sn", FileRawInput);
}
我在第8行收到以下错误:
Unhandled exception at 0x64F4C6D1 in ias-agent.exe: 0xC00001A5: An invalid exception handler routine has been detected (parameters: 0x00000003).
我已经尽量避免使用string
类,我想暂时保持这种方式。我所要做的就是将RawFileInput
的两个字符串相加,然后将RawFileInput
的值与bzipCompressionOutput
相加,最后将.bz2
连接到bzipCompressionOutput
的末尾。
在他的书第4章的最后一页:"C++编程语言"Bjarne Stroustrup,C++的创建者说:
首选
strings
而非C样式字符串
这只是建议,但我鼓励你遵循它。
但你真正的问题是你在践踏内存——你的FileRawInput
中有而不是sizeof(FileRawInput)
wchar_t
,同样,bzipCompressedOutput
阵列中没有sizeof(bzipCompressedOutput)
,两者中都有MAX_PATH
wchar_t
。问题是sizeof
会告诉你数组中的字节数,但如果每个元素都大于1个字节,那么你就错误地告诉了wcsncpy
和wscncat
你的字符数。wchar_t
通常是2个字节:https://msdn.microsoft.com/en-us/library/s3f49ktz.aspx这意味着您实际上是在呼叫wcsncpy(FileRawInput, WorkingDirectory, 200)
。超出已分配的内存100wchar_t
秒。更正此错误将删除您的segfault。
但是,为了打印宽字符串,您需要正确地使用%ls
修饰符来修改wprintf
。
最终,你的代码应该是这样的:
wprintf(L"Attempting to compress %ls%lsn", WorkingDirectory, File);
wchar_t FileRawInput[MAX_PATH];
wcsncpy(FileRawInput, WorkingDirectory, MAX_PATH);
wcsncat(FileRawInput, File, MAX_PATH);
wchar_t bzipCompressedOutput[MAX_PATH];
wcsncpy(bzipCompressedOutput, FileRawInput, MAX_PATH);
wcscat(bzipCompressedOutput, L".bz2");
wprintf(L"Output of string bzip: %lsn", bzipCompressedOutput);
wprintf(L"Output of string raw: %lsn", FileRawInput);
实时示例
编辑:
OP已经默认了Bjarne Stroustrup的建议,并使用了wstring
:将字符数组连接在一起。但对于仍坚持使用这些C风格函数的其他人来说,MAX_PATH
必须足够大,以容纳wsclen(WorkingDirectory) + wsclen(File) + wsclen(L".bz2")
和L' '
字符,因此在该函数上放置if语句可能会很有用,或者:
assert(MAX_PATH > wsclen(WorkingDirectory) + wsclen(File) + wsclen(L".bz2"))