正在尝试传递数组的指针:
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;
}
问题是多方面的:
-
malloc
非 POD 类型,以便它们的构造函数不会运行(灾难性( - 未能
free
你malloc
的事情(不好( -
malloc
C++(不时尚( - 当您的意思是
aaa** a
时传递aaa* a[]
(有效但具有误导性( cout
和endl
上没有#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而不是原始指针,那就太好了。