2012-01-04 217 views
3

我有代码在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上?

谢谢。

+2

只是为了阐述的答案...崩溃在Mac上(可能使用GCC任何平台),因为性病的'内部状态: :设置为全部NULL指针时,string'恰好无效。当一个类包含一个具有不平凡构造函数的成员(比如具有实际定义的构造函数)时,它的构造函数被定义为使用简单构造函数将成员归零,并调用非平凡构造函数。所以不要担心'eTransportType'。当然,最好的方法是命名嵌套类型并定义它的构造函数,从而避免使用'memset'。 – Potatoswatter 2012-01-04 02:01:18

+2

当你违反规则时,有时你会逃避,有时候你不会。 – 2012-01-04 02:09:14

回答

14

您在覆盖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"; 
11

在非数据类型上调用memset()是非法的。包含std::string成员的结构不是POD。