是否有可能拆分内存块或在中间访问它

时间:2015-05-19 11:54:04

标签: c++ memory-management

我正在寻找一个选项" split" allocated memory,(之前已分配malloc),以便在部分中存储一些objects of different type and size

我只是移动pointer并将memory block作为一个部分来尝试:

int main()
{
   void* ptr1 = malloc(sizeof(int) * 3);
   int*  ptr2 = (static_cast<int*>(ptr1) + sizeof(int));

   ptr1 = new (ptr1)int(5);
   ptr2 = new(ptr2) int(7);

   return 0;
}

(是的,没有免费的(),我知道,但这只是一个例子)

问题是,pointer adress这种方式是可靠的,可以在每个c ++编译器下使用吗? 或者是否有更好的可能性来执行此操作,甚至可以将memory block拆分为多个部分。

(我既不想使用array也不想使用3次new / malloc,请不要像#34那样的答案;为什么要这样做?!& #34;我想做到这一点......)

3 个答案:

答案 0 :(得分:1)

同质容器

改为使用std::array

std::array<int, 3> arr;
arr[0] = 5;
arr[1] = 7;
arr[2] = 9;

不需要动态分配,也不需要手动内存管理。这样,您就可以拥有连续的内存并轻松访问每个元素。不仅如此,您还可以免费获得标准兼容代码。

如果您确实需要动态分配(例如,因为您的代码使用了大量的对象),那么只需使用std::vector,如下所示:

std::vector<int> arr(3);
arr[0] = 5;
arr[1] = 7;
arr[2] = 9;

我知道。真是太好了。

异构容器

另一方面,如果您想要一个不同大小的容器,可以使用std::tuple,例如:

std::tuple<Type1, Type2, Type3, ...> tuple;

变体

最后,如果您要实现的目标类似于union,请查看您的评论:

  

在零件中存储一些不同类型和大小的物体。

然后您可以使用boost::variant代替,这将允许您在同一内存位置有效地存储不同类型的对象。

如果您事先(在编译时)不了解所有可能的类型,那么使用boost::any可能是个好主意。

答案 1 :(得分:1)

  

是以这种方式移动指针地址可靠并且可以在每个c ++编译器下使用吗?

是的,有几点需要注意:

  • 每个指针必须与您在那里创建的类型正确对齐。从malloc获得的基址将针对任何类型正确对齐,因此只需确保每个偏移量是该类型对齐要求的倍数。
  • 使用非平凡析构函数的类型应在使用后手动销毁。

但是,您已经搞乱了示例中的指针算法:转换为int,然后将sizeof(int)添加到指针。结果是您添加了16个字节而不是预期的4个字节(假设为4字节int类型),超出了分配的末尾。如果要处理字节偏移,请转换为char*

  

有更好的可能性吗

如果在编译时已知布局,则只需使用structtuple。如果没有,那么这可能是你唯一适度的选择。

答案 2 :(得分:0)

  

问题是,是否可以将指针地址移动到可靠的位置,并且可以在每个c ++编译器下使用?

答案:是的,有几种方式

// p points to 3 ints
int* p = reinterpret_cast<int*>(malloc(sizeof(int) * 3));

int* p_plus_1 = p + 1;  // the '1' is automatically scaled by the size of an int
*p_plus_1 = 10;

// demonstrate equivalence
assert(*(p+1) == *p_plus_1);
assert((p+1) == p_plus_1);
assert((p+1) == &p[1]);
assert(*p_plus_1 == p[1]);
  

或者是否有更好的可能性,甚至可以将内存块分成几个部分。

答案:取决于你想要实现的目标。需要更多信息。