1

我正在 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 块处理所有断言和错误。我该怎么做?

4

2 回答 2

13

如果使用new[]你必须使用delete[],不是free()delete。代替:

free(LocalBuffer);

和:

delete[] LocalBuffer;

似乎没有理由动态分配内存。缓冲区的大小是一个编译时间常数,不大(没有堆栈溢出),并且似乎不需要缓冲区超出分配的范围。

由于这是 c++,强烈建议使用std::stringwhich 将为您处理动态内存管理,并且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()are char*, not ,因此如果函数修改参数const char*,将字符串文字传递给函数将导致未定义的行为。

于 2013-05-13T07:13:07.573 回答
2

首先,你是用 C 还是 C++ 编程。您提供的代码看起来像 C,但您说的是 try/catch 块,它只能是 C++。

在 C++ 中,使用std::ostringstreamstd::string。任何其他解决方案都是不正确的。

在 C 中,您应该使用snprintf, 而不是sprintf. 安全使用几乎是不可能的sprintf。(例如,有多少个字符LogFileCharName。)并且不要在不需要时使用动态分配。(这也适用于 C++;您显示的代码中不应该有newor delete(nor mallocnor free)。

至于出了什么问题,您显示的代码中至少有两个可能的问题:您使用 分配内存 new[],但使用free(未定义的行为)释放它,并且您没有LogFileCharName在调用之前检查长度sprintf,所以您可能会覆盖缓冲区的末尾。

于 2013-05-13T07:45:59.420 回答