2012-01-04 4 views
3

Windows에서 작동하지만 현재 MAC에 포팅 중이며 Xcode 3.2.5 C/C++ 컴파일러 버전 GCC 4.2를 사용하는 코드가 충돌합니다.memset이 std :: string 할당에서 크래시를 일으키고 있습니다.

나는 그것을 memset 호출로 좁혔다. memset을 주석 처리하면 작동하고 코드를 다시 넣으면 충돌이 발생합니다. 나는이 가지고 CPP 파일에 다음

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; 

:

가 내 헤더 파일에 다음과 같습니다 구조가

DeviceParams Param; 
memset(&Param, nil, sizeof(Param)); 

을 ... 나중에 나는이 있습니다

pParam->deviceNodes[index].deviceId = "some string"; // <----- Line that crashes with memset 

내가 이전에 memset 호출을 제거하면 모든 것이 제대로 작동합니다. memset을 호출하기 전에 디버거를 살펴보면 구조체의 문자열은 \ 0이고 memset 이후는 nil입니다.

왜 할당 행에서 nil 문자열이 충돌하며 MAC에서만 발생합니까?

감사합니다.

+2

그냥 답변에 정교을 (가능성 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

memset()POD 데이터 형식으로 호출하는 것은 C++에서 불법입니다. std::string 회원을 포함하는 구조물은 POD가 아닙니다.

관련 문제