我正在Visual Studio 2010中编写Win32控制台应用程序。
考虑一个以char*
为参数的函数。
以下是功能原型:
void WriteApplicationFile(char *mappname,char* MessageString)
{
//Do some File related stuffs.
}
现在以下调用正常运行:
WriteApplicationFile("FirstOne", "Append Me");
WriteApplicationFile("FirstOne", "Append Another");
但是如果我用一些字符数组的东西尝试相同的东西,这会给我断言,并把我扔上装配。
以下代码无效:
char * LocalBuffer = new char[100];
sprintf(LocalBuffer,"Number of jobs in Queue %d",JobsCount);
WriteApplicationFile("SAAZshadowProtect",LocalBuffer);
free(LocalBuffer);
LocalBuffer = NULL;
//Work fine.
//...
LocalBuffer = new char[100];
sprintf(LocalBuffer,"Log file name %s",LogFileCharName);
WriteApplicationFile("SAAZshadowProtect",LocalBuffer);
free(LocalBuffer); // I got assertion here..
LocalBuffer = NULL;
我哪里错了?
还有一件事是我想用try-catch块处理所有断言和错误。我该怎么做?
答案 0 :(得分:13)
如果使用new[]
,您必须使用delete[]
,而不是free()
或delete
。替换:
free(LocalBuffer);
使用:
delete[] LocalBuffer;
似乎没有理由动态分配内存。缓冲区的大小是编译时常量,不是很大(没有堆栈溢出),并且缓冲区似乎不需要超出分配范围。
因为这是c ++强烈建议使用std::string
来处理动态内存管理和std::ostringstream
这是类型安全的,并避免指定固定大小的缓冲区而不是sprintf()
:
#include <sstream>
#include <string>
std::ostringstream out;
out << "Number of jobs in Queue " << JobsCount;
const std::string s(out.str());
如果需要访问c风格的字符串,请使用std::string::c_str()
。
此外,WriteApplicationFile()
的参数类型为char*
,而不是const char*
,因此将字符串文字传递给函数会导致未定义的行为如果函数修改参数。
答案 1 :(得分:2)
首先,您是使用C语言编写还是使用C ++编程。你提供的代码 看起来像C,但你说的是try / catch块,它只能 是C ++。
在C ++中,使用std::ostringstream
和std::string
。任何其他
解决方案完全不正确。
在C中,您应该使用snprintf
,而不是sprintf
。它是
几乎不可能安全地使用sprintf
。 (多少个字符
例如,在LogFileCharName
中。)并且不使用动态
你不需要分配。 (这适用于C ++
好;应该没有new
或delete
(也不是malloc
也不是
您显示的代码中的free
)。
至于出了什么问题,至少有两种可能
您显示的代码中的问题:您正在分配内存
new[]
,但使用free
(未定义的行为)释放它,以及
你之前没有检查LogFileCharName
的长度
调用sprintf
,所以你可以覆盖结束
缓冲液中。