使用malloc为数组获取空间

时间:2018-01-22 18:13:52

标签: c++ malloc

尝试传递数组的指针:

class aaa{
public:
    int a ;
    int b ;
    std::string c ;
};


void abc(aaa* a [])
{
    *a = (aaa*)malloc(sizeof(aaa)* 5);
    a[0]->c ="ddd" ;
    a[1]->c ="ccc" ;  //crash
    a[2]->c ="eee" ;
}

int main() {

    aaa * a;
    abc(&a);

    cout << "!!!Hello World!!!"<< a++->c << endl; 

    cout << "!!!Hello World!!!"<< a++->c << endl; 
    return 0;
}

在第二个数组元素赋值中,我崩溃了。问题出在哪儿? malloc没有创造足够的空间吗?

UPD。

由于某种原因,我无法更改功能void abc(aaa* a [])签名。即使它看起来不太好也不是错误的签名。

我根据recomendations在答案中更新了程序,但我仍然在获取第二个数组元素成员时崩溃:

cout << "!!!Hello World!!!"<< a[1].c << endl;

为什么呢?我在下面的代码中做错了什么?

struct aaa{
public:
    int a ;
    int b ;
    std::string c ;
};


int abc(aaa* a [])
{
    int asize =5;
    *a = (aaa*)malloc(sizeof(aaa) * asize);
    for (int i;i<asize;i++)
    {
        a[i] = new aaa();
    }
    a[0]->c ="ddd" ;
    a[1]->c ="ccc" ;
    a[2]->c ="eee" ;
return asize;
}

int main() {
    aaa * a;
    int asize=abc(&a);

    cout << "!!!Hello World!!!"<< a[0].c << endl;
    cout << "!!!Hello World!!!"<< a[1].c << endl; //crash
    cout << "!!!Hello World!!!"<< a[2].c << endl;

    for (int i=0; i<asize;i++)
    {
        cout << "free "<<i<<endl;
        a[i].~aaa();
    }
    free(a);
    cout << "end"<<endl;
    return 0;
}

2 个答案:

答案 0 :(得分:6)

问题是多方面的:

  1. malloc非POD类型,因此他们的构造函数不运行(灾难性)
  2. freemalloc(坏)
  3. 的事情
  4. malloc完全使用C ++(非时尚)
  5. 当您的意思aaa* a[](有效但具有误导性)时传递aaa** a
  6. #includecout上没有endl或名称空间限定符(测试用例无效)
  7. 以下是您的程序应该的样子:

    #include <vector>
    #include <string>
    #include <iostream>
    
    class aaa
    {
    public:
        int a;
        int b;
        std::string c;
    };
    
    
    std::vector<aaa> abc()
    {
        std::vector<aaa> result;
        result.reserve(3);
    
        result.push_back({0, 0, "ddd"});
        result.push_back({0, 0, "ccc"});
        result.push_back({0, 0, "eee"});
    
        return result;
    }
    
    int main()
    {
        const auto a = abc();
    
        std::cout << "!!!Hello World!!!"<< a[0].c << std::endl;
        std::cout << "!!!Hello World!!!"<< a[1].c << std::endl;
        std::cout << "!!!Hello World!!!"<< a[2].c << std::endl;
    }
    

    Live demo

    或者,保持五个前期元素分配:

    std::vector<aaa> abc()
    {
        std::vector<aaa> result(5);
    
        result[0].c = "ddd";
        result[1].c = "ccc";
        result[2].c = "eee";
    
        return result;
    }
    

    当你写C ++时,我强烈建议忘记你对C的所有了解。

答案 1 :(得分:0)

您可以使用malloc,但仍需要调用构造函数,因此需要new,这会失败使用malloc的想法。

const int asize = 5;

void abc(aaa*& a)
{
    a = (aaa*)malloc(sizeof(aaa) * asize); // you need to release memory later
    for (int i = 0; i < asize; ++i) {
        new (a+i) aaa(); // you need to call constructors to intialize string
    }
    // now you can use strings
    a[0].c = "ddd";
    a[1].c = "ccc";
    a[2].c = "eee";
}

int main() {
    aaa * a;
    abc(a);

    cout << "!!!Hello World!!!" << a[0].c << endl;
    cout << "!!!Hello World!!!" << a[1].c << endl;

    // finally you need to call destructors
    for (int i = 0; i < asize; ++i) {
        a[i].~aaa();
    }
    free(a);
    return 0;
}

在向您展示如何使其发挥作用后,我想提出另一种解决方案。如果您关心记忆并且不想使用std::vector,则可以使用std::unique_ptr

std::unique_ptr<aaa[]> data;
data = std::make_unique<aaa[]>(asize);
data[0].c = "text";
cout << data[0].c;
// no need to manually release memory

编辑: 截至更新的问题。如果你真的想传递指针数组,那么你可以执行以下操作:

const int asize = 5;

void abc(aaa* a[]) {
    // If array is really big, then you probably should preallocate memory and call placement new for every element.
    for (int i = 0; i < asize; ++i) {
        a[i] = new aaa; // again, you have to release memory 
    }
    // now you can use strings
    a[0]->c = "ddd";
    a[1]->c = "ccc";
    a[2]->c = "eee";
}

int main() {
    aaa * a[asize];
    abc(a);

    cout << "!!!Hello World!!!" << a[0]->c << endl;
    cout << "!!!Hello World!!!" << a[1]->c << endl;

    for (int i = 0; i < asize; ++i) {
        delete a[i];
    }
    return 0;
}

如果你可以使用unique_ptr而不是原始指针,这将是非常好的。