2012-01-04 5 views
3

У меня есть код, который работает в Windows, но теперь, когда я переношу на MAC, используя Xcode 3.2.5 C/C++ Compiler Version GCC 4.2, он сбой.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 они равны нулю.

Почему nil сбой строки на линии назначения и только на MAC?

Спасибо.

+2

Просто разработать на ответах ... он выходит из строя на Mac (и, вероятно, на любой платформе с помощью GCC), так как внутреннее состояние 'станд: : string' оказывается недопустимым при установке всех указателей NULL. Когда класс содержит элемент с нетривиальным конструктором (например, конструктор с фактическим определением), его конструктор определяется как нулевой элемент с тривиальными конструкторами, а также вызывает нетривиальные конструкторы. Поэтому не беспокойтесь о 'eTransportType'. Конечно, лучшим способом было бы назвать вложенный тип и определить его конструктор, тем самым избегая «memset». – Potatoswatter

+2

Когда вы нарушаете правила, иногда вам это удается, а иногда нет. –

ответ

14

Вы переписываете внутренние данные deviceId, делая memset по всему миру; никогда не делайте memset ничего, кроме POD data type. Это 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

В C++ запрещено называть memset() по типу данных не POD. Структуры, содержащие std::string, не являются POD.

Смежные вопросы