使用malloc/realloc用于包含std向量的类/结构的数组 [英] Using malloc/realloc for array of classes/structs including std vector
问题描述
我有一个问题,请问malloc/realloc内存将包含一个包含std向量的class/struct(我尝试过struct和class的问题仍然存在)数组的成员.我知道我可以通过使用new和std数组容器类来解决此问题.但是,我想更好地理解为什么当我使用realloc而不是malloc时,以下的小代码崩溃(因为在将较大的代码项目从C转换为C ++的情况下遇到了此问题).似乎我也不一定必须在类/结构中设置向量的初始大小(某些编译器允许某些不..)-那么类中的向量是什么-舒适的指针?
I have a question wrt malloc/realloc memory that will contain an array of class/struct (i tried both struct and class the issue remains) members that include std vectors. I know I can circumvent the problem by using new and std array container class. However, I'd like to better understand why the following little code crashes when I use realloc instead of malloc (as I encountered this problem in the context of transitioning a larger code project from C to C++). It also seems that I cannot necessarily set an initial size of a vector in a class/struct (some compilers allow some don't ..)- so what is a vector in a class - a comfortable pointer?
谢谢, 凯
#include <stdlib.h>
#include <limits.h>
#include <float.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include <vector>
/* mpic++ -O3 -ffast-math -pedantic vec-alloc.cpp -o vec-alloc */
using namespace std;
class float_vector{
public:
double x;
double y;
double z;
float_vector() : x(0), y(0), z(0) {};
};
class voxel{
public:
float_vector x;
vector<double> y;
voxel() : x() {};
};
int main(){
int i;
double d =1.111;
voxel v0, *Comp, *Comp2;
/* dynamically allocate memory */
Comp= (voxel*)malloc(10*sizeof(voxel));
for(i=0;i<10;++i) Comp[i] = v0;
printf("malloc done\n");
/* dynamically re-allocate memory */
Comp2= (voxel*)malloc(sizeof(voxel));
printf("realloc done\n");
for(i=0;i<10;++i){
Comp2 =(voxel*)realloc(&Comp2[0], (i+1)*sizeof(voxel));
Comp2[i] = v0;
}
printf("realloc done\n");
for(i=0;i<10;++i) Comp[i].y.push_back(d);
for(i=0;i<10;++i) printf("%lf\n",Comp[i].y[0]);
for(i=0;i<10;++i) Comp2[i].y.push_back(d); // this crashes
for(i=0;i<10;++i) printf("%lf\n",Comp2[i].y[0]);
return 1;
}
推荐答案
如果对非POD类使用malloc()
,则必须手动调用构造函数(通过放置new
)和析构函数.
If you use malloc()
with non-POD classes, you must call constructors (via placement new
) and destructors manually.
使用未正确构造的对象会导致未定义的行为,这通常会导致指针崩溃.
Using an object which was not constructed properly results in undefined behavior, which often means a crash when it comes to pointers.
很明显,在没有适当破坏对象的情况下释放对象的内存也会导致UB.
Obviously, freeing a memory for object without a proper destruction of it causes UB too.
您的代码必须如下所示:
Your code must look like this:
MyClass *arr = (MyClass *) malloc(10 * sizeof (MyClass));
for (int i = 0; i < 10; i++)
new (arr + i) MyClass; // This line calls constructors
// Do something with the array here
for (int i = 0; i < 10; i++)
arr[i].~MyClass(); // This line calls destructors.
free(arr);
此要求还意味着您不能将realloc()
与非POD类型一起使用,因为它不会为您调用旧数组的析构函数,而不会为新数组调用析构函数.
This requirement also means that you can't use realloc()
with non-POD types, because it wont call destructors for the old array and contructors for the new one for you.
手动重新分配代码可能看起来像这样:
Manual reallocation code might look like this:
MyClass *new_ptr = (MyClass *) malloc(new_size * sizeof (MyClass));
for (int i = 0; i < new_size; i++)
new (new_ptr + i) MyClass((MyClass &&) old_ptr[i]);
for (int i = new_size; i < old_size; i++)
new (new_ptr + i) MyClass;
for (int i = 0; i < old_size; i++)
old_ptr[i].~MyClass();
free(old_ptr);
并且请记住,上面的代码并不是真正的异常安全.如果构造函数引发异常并捕获了异常,那么您要确保正确地破坏了所构造的对象. 感谢@SteveJessop.
现在,当您了解为什么在C ++中通常应避免使用malloc()
/free()
的时候,我希望您会返回到更安全的new
/delete
来完成所有的构造和工作.毁了你.
Now when you understand why malloc()
/free()
usually should be avoided in C++, I hope you'll return to a lot more safe new
/delete
, which do all that construction and destruction for you.
这篇关于使用malloc/realloc用于包含std向量的类/结构的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!