从编写的这里来看,new在免费存储中分配,而malloc使用堆,这两个术语通常意味着相同的东西。
通过编写的这里,realloc可以将内存块移动到一个新位置。如果空闲存储和堆是两个不同的内存空间,那么它是否意味着任何问题?
具体来说,我想知道它是否安全使用
int* data = new int[3];
// ...
int* mydata = (int*)realloc(data,6*sizeof(int));如果没有,还有其他方法可以安全地分配realloc内存吗?我可以分配新的区域并对内容进行memcpy,但据我所知,如果可能的话,realloc可以使用相同的区域。
发布于 2015-11-14 08:30:13
您只能通过realloc (或家庭,如calloc)分配已分配的内容。
这是因为底层的数据结构可以跟踪内存的空闲和使用区域,这是完全不同的。
这很可能,但不能保证C++ new和C malloc使用相同的底层分配器,在这种情况下,realloc可以同时适用于这两种情况。但从形式上讲,那是在UB-土地上。在实践中,这只是不必要的冒险。
C++不提供与realloc相对应的功能。
最近的是像std::vector这样的容器的自动重新分配(内部缓冲区)。
C++容器的设计方式不允许使用realloc。
而不是所呈现的代码
int* data = new int[3];
//...
int* mydata = (int*)realloc(data,6*sizeof(int));…这样做:
vector<int> data( 3 );
//...
data.resize( 6 );但是,如果您绝对需要realloc的一般效率,如果您必须接受new作为原始分配,那么您唯一的提高效率的方法就是使用特定于编译器的方法,即知道realloc在这个编译器中是安全的。
否则,如果您绝对需要realloc的一般效率,但不被迫接受new,那么您可以使用malloc和realloc。然后,使用智能指针可以获得与C++容器相同的安全性。
发布于 2015-11-14 08:36:10
对malloc/calloc/realloc的唯一可能相关的限制是,C++的malloc/calloc/realloc不能用::operator new来实现,它的free不能用::operator delete来实现(per C++14 c.mallocp3-4)。
这意味着您正在寻找的保证在C++中不存在。但是,这也意味着您可以根据::operator new实现malloc。如果你这样做,那么理论上,::operator new的结果可以传递给realloc。
实际上,您应该担心new的结果与::operator new的结果不匹配的可能性。例如,C++编译器可以组合多个new表达式来使用一个::operator new调用。这是编译器在标准不允许的情况下已经做的事情,IIRC,而标准现在允许这样做(per C++14 expr.newp10)。这意味着,即使您走了这条路线,您仍然无法保证将您的new指针传递给realloc做任何有意义的事情,即使它不再是未定义的行为。
发布于 2015-11-14 08:32:48
一般来说,不要那么做。如果您使用的是具有非平凡初始化的用户定义类型,那么在重新分配复制释放的情况下,对象的析构函数将不会被realloc调用为。复制构造函数在复制时也不会被称为。这可能由于不正确地使用对象生存期而导致未定义的行为(请参阅C++标准§3.8Object生存期,basic.life)。
1对象的生存期是对象的运行时属性。如果一个对象是一个类或聚合类型,并且它或它的一个成员被一个构造函数初始化,而不是一个普通的默认构造函数,那么它就被称为具有非平凡的初始化。注意:通过简单的复制/移动构造函数进行初始化是非常重要的初始化。-end注记 T类型对象的生存期从以下时间开始: -获得T型的适当对齐度和尺寸的存储器,以及 -如果对象具有非平凡的初始化,则它的初始化已经完成。 T类型对象的生存期在以下情况下结束: -如果T是具有非平凡析构函数(12.4)的类类型,则析构函数调用将启动,或 -物品所占的储存物被重复使用或释放。
后来(强调我的):
3在整个国际标准中赋予对象的属性仅适用于给定对象在其生存期内的。
因此,您真的不希望在对象的生命周期中使用它。
https://stackoverflow.com/questions/33706528
复制相似问题