使用 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不能创造足够的空间吗?

上。

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

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

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;
}

问题是多方面的:

  1. malloc非 POD 类型,以便它们的构造函数不会运行(灾难性(
  2. 未能freemalloc的事情(不好(
  3. malloc C++(不时尚(
  4. 当您的意思是aaa** a时传递aaa* a[](有效但具有误导性(
  5. coutendl上没有#include或命名空间限定符(无效的测试用例(

以下是程序的外观:

#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;
}

(现场演示(

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

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的一切。

你可以

使用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而不是原始指针,那就太好了。

最新更新