memset导致std :: string赋值崩溃
问题描述:
我有代码在Windows上工作,但现在我正在使用Xcode 3.2.5 C/C++编译器版本GCC 4.2移植到MAC,它崩溃了。memset导致std :: string赋值崩溃
我已经缩小到一个memset调用。如果我将memset注释掉,它会起作用,如果我把它放回代码崩溃。
我有一个看起来像这样在我的头文件的结构:
typedef struct
{
int deviceCount;
struct
{
#define MAX_DEVICE_ID 256
#define MAX_DEVICE_ENTRIES 10
std::string deviceId; // Device name to Open
TransportType eTransportType;
} deviceNodes[MAX_DEVICE_ENTRIES];
} DeviceParams;
在CPP文件
然后,我有这样的:
DeviceParams Param;
memset(&Param, nil, sizeof(Param));
...后来我有这样的:
pParam->deviceNodes[index].deviceId = "some string"; // <----- Line that crashes with memset
就像我之前说的,如果我删除memset调用一切正常。如果我在调用memset之前查看调试器,则结构中的字符串是\ 0,在memset之后它们是零。
为什么零字符串会在分配行上崩溃并且只在MAC上?
谢谢。
答
您在覆盖deviceId
的内部数据时全部使用memset
;除了POD data type之外,千万不要做memset
。这是C++,我们有构造函数。你的代码应该是这个样子:
struct DeviceParams
{
int deviceCount;
struct DeviceNode
{
DeviceNode() : eTransportType() { } // initialise eTransportType
// to 0, deviceId initialises itself
static const int MAX_DEVICE_ID = 256;
static const int MAX_DEVICE_ENTRIES = 10;
std::string deviceId; // Device name to Open
TransportType eTransportType;
} deviceNodes[DeviceNode::MAX_DEVICE_ENTRIES];
};
然后
DeviceParams Param;
// get a pointer to Param in pParam
pParam->deviceNodes[index].deviceId = "some string";
答
在非数据类型上调用memset()
是非法的。包含std::string
成员的结构不是POD。
只是为了阐述的答案...崩溃在Mac上(可能使用GCC任何平台),因为性病的'内部状态: :设置为全部NULL指针时,string'恰好无效。当一个类包含一个具有不平凡构造函数的成员(比如具有实际定义的构造函数)时,它的构造函数被定义为使用简单构造函数将成员归零,并调用非平凡构造函数。所以不要担心'eTransportType'。当然,最好的方法是命名嵌套类型并定义它的构造函数,从而避免使用'memset'。 – Potatoswatter 2012-01-04 02:01:18
当你违反规则时,有时你会逃避,有时候你不会。 – 2012-01-04 02:09:14