使用malloc/realloc用于包含std向量的类/结构的数组 [英] Using malloc/realloc for array of classes/structs including std vector

查看:95
本文介绍了使用malloc/realloc用于包含std向量的类/结构的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,请问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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆