【问题标题】:memset is causing a crash on std::string assignmentsmemset 导致 std::string 分配崩溃
【发布时间】:2012-01-04 01:49:10
【问题描述】:

我的代码可以在 Windows 上运行,但现在我要移植到 MAC,使用 Xcode 3.2.5 C/C++ 编译器版本 GCC 4.2,它会崩溃。

我已将其范围缩小为 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。

为什么 nil 字符串会在赋值行上崩溃并且只在 MAC 上?

谢谢。

【问题讨论】:

  • 只是为了详细说明答案......它在 Mac 上崩溃(可能任何使用 GCC 的平台)因为std::string 的内部状态在设置为所有 NULL 指针时碰巧是无效的。当一个类包含具有非平凡构造函数的成员(例如具有实际定义的构造函数)时,其构造函数被定义为将具有平凡构造函数的成员清零,并调用非平凡构造函数。所以不用担心eTransportType。当然,最好的方法是命名嵌套类型并定义其构造函数,从而避免memset
  • 当你违反规则时,有时你会逍遥法外,有时你不会。

标签: c++ xcode string crash memset


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-06
      • 1970-01-01
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      • 2012-09-17
      相关资源
      最近更新 更多