结构的std :: string成员的EXC_BAD_ACCESS错误

时间:2014-07-01 08:17:50

标签: c++ c++11 malloc stdstring

在访问std :: string类型的struct成员时,弹出错误 Bus Error:10 。代码如下。

#include <iostream>
#include <string>

struct KeyValuePair {
    std::string key;
    std::string value;
};

struct KeyValuePair *temp = (struct KeyValuePair *) malloc(sizeof(struct KeyValuePair));


int main(void) {

    temp->value = "|";

    temp->value += "someval|";

    std::cout << temp->value << std::endl;

    return 0;
}

在代码上运行gdb会在 temp-&gt; value =“|”行显示以下内容。

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00007fff8d99e524
0x00007fff898dc7ca in std::string::_M_mutate ()

从上面的消息中我理解的是我的代码试图访问无效/未经授权的内存区域。

我的问题:虽然我已经使用malloc来获取全局变量 temp 的内存区域,但为什么我无法访问它。我错过了什么请帮忙。

3 个答案:

答案 0 :(得分:3)

您需要使用new而不是malloc来确保构造std::string个对象。

KeyValuePair *temp = new KeyValuePair;

当您需要销毁结构时,请使用delete

delete temp;

作为一般经验法则,在C ++编码时不应使用malloc。请改用new。出于这个原因。

那就是说,对于你的简单例子,似乎没有真正需要动态分配。您可以避免动态分配,如下所示:

KeyValuePair temp;

答案 1 :(得分:3)

您在C ++中使用C构造。完全消除malloc

KeyValuePair temp; // Yes, that simple.

int main( ) {

    temp.value = "|";

答案 2 :(得分:2)

C和C ++之间存在差异:

  • 在C中,struct的实例没有固有的不变,它只是位于内存中
  • 在C ++中,structclass的一个实例有一组不变量,它们由构造函数建立并在整个生命周期内由公共接口维护

这显示在这里:

  • malloc,作为C构造,只会保留一些原始内存
  • new,作为C ++构造,不仅会保留一些原始内存,还会调用适当的构造函数,从而建立实例不变量(如果有的话)

注意:如果new使用int等内置类型,new int实际上并未初始化任何内容......

因此,访问temp->value时,您正在访问未初始化的内存。这是未定义的行为(任何可能发生的事情),并且,在您的情况下,程序遵循一些狂野指针并落在存储区域上,禁止访问。

所以,暂时忘掉那些C-isms:常规C ++结构将确保为你适当地调用构造函数。

KeyValuePair temp;

int main() {
    // ...
}

或者,如果你真的需要一个动态分配的值(用于什么?):

KeyValuePair* temp = new KeyValuePair();

int main() {
    // ...
}

但是你必须考虑在某个时刻deletetemp调用{{1}},这只是一次,这要复杂得多。没有智能指针,这是一场失败的比赛。