2012-01-04 115 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。