如果我替换所有operator new我可以签名的签名,至少在我测试的实现上,我看到标准容器调用我的替换版本来分配内存.
这是否由标准保证?也就是说,实现使用优化版本是不合法的,该版本没有将我的替换函数称为标准容器下的内存?
如何有效地调整使用符合标准的C++分配器分配的数组的大小?我知道在C++ alloctor界面中没有提供重新分配的工具,但是C++ 11版本是否使我们能够更容易地使用它们?假设我有一个定义vec了复制赋值运算符的类foo& operator=(const foo& x).如果x.size() > this->size(),我被迫
foo.foo.x.size().有没有什么方法可以让我更轻松地重新分配内部存储而foo无需经历所有这些?如果您认为它有用,我可以提供一个实际的代码示例,但我觉得这里没有必要.
在C,我们有malloc(),free()和realloc().在C++中,我们有new(),delete()而且他们的阵列版本.有C++ realloc功能吗?我在嵌入式领域实现了一些低级的东西,并且意识到没有realloc与C++函数配对的功能,并且想确保我没有遗漏任何东西.我猜测"将new place"放入一个新的,独立的缓冲区是最接近的匹配,但我想确定.
稍微重复一下这个问题,因为我得到的回答有点远.
我已经实现了设备级malloc/new/realloc/etc. 我的嵌入式设备上的函数,并想要仔细检查,以确保没有我不知道的C++ realloc类型函数.
我有一个内存接口,分离出获取地址空间与附加后备存储.(在Linux下,接口管理的地址空间池是mmap'ed MAP_ANONYMOUS和MAP_NORESERVE,madvise'ed MADV_DONTNEED和mprotect'ed PROT_NONE.然后通过madvise MADV_WILLNEED和mprotect PROT_READ,PROT_WRITE和PROT_EXEC附加支持.)
这个界面允许我分配大量的地址空间,同时懒洋洋地获取实际的物理内存.我想用它来创建一个"懒惰的向量",它在适当的点上提出后备存储请求,但是当它增长时从不复制向量的当前内容.
鉴于标准库的分配器的语义是这样的方案可能吗?感激地接受指针,提示或其他指导.
在 C 中创建自动扩展数组(如 C++ 的 std::vector)时,通常(或者至少是常见的建议)在每次填充时将数组的大小加倍,以限制调用量,以realloc避免尽可能复制整个数组。
例如。我们首先为 8 个元素分配空间,插入 8 个元素,然后为 16 个元素分配空间,再插入 8 个元素,再分配 32 个元素,等等。
但realloc如果可以扩展现有的内存分配,则不必实际复制数据。例如,以下代码在我的系统上仅执行 1 次复制(初始 NULL 分配,因此它不是真正的副本),即使它调用了realloc10000 次:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i;
int copies = 0;
void *data = NULL;
void *ndata;
for (i = 0; i < 10000; i++)
{
ndata = realloc(data, i * sizeof(int));
if (data != ndata)
copies++;
data = ndata;
}
printf("%d\n", copies);
}
Run Code Online (Sandbox Code Playgroud)
我意识到这个例子非常临床 - 现实世界的应用程序可能会有更多的内存碎片并且会做更多的副本,但即使我在循环之前进行一堆随机分配realloc,它也只会在 …
如果您觉得需要realloc()-而且很多人都这样做-那么请考虑使用标准库向量。
我将通过同意std::vector更好的原因(因为许多原因)来开始我的问题,而我个人总是选择使用它,而不是使用C内存分配编写自己的动态数组。
但是,std::vector由于C ++没有等效的内存,内存会随着内存的增长而碎片化realloc(编辑澄清一下,我知道std::vectors的存储是连续的,不会碎片化,我的意思是分配和取消分配导致的内存空间碎片化,这realloc可以避免扩展现有分配)。那么总是推荐它公平realloc吗?小心翼翼,难道您不能编写类似于std::vectorC分配函数那样工作的东西,它可以在不移动其地址和复制现有元素的情况下增加其内存,使其在碎片和性能方面都达到或超过或提高吗?
与此相关的(奖励问题!),为什么 C ++没有与之等效的东西realloc?忽略一种专注于性能的语言,这似乎很奇怪。Bjarne的FAQ中的部分恰好具有该标题(没有强调),但是答案并未解决“为什么”的问题。只是偶然的遗漏吗?是否有与如何一些基本的不相容new/ delete工作?它真的不能真正带来实际的好处吗?
编辑:好的,所以我忽略了C的复杂性realloc- std::vector不能使用重写,realloc因为它仅适用于POD,不抛出等。在某些情况下,也许编写一个仅用于POD的容器来处理棘手问题是个好主意。无论如何,更有趣的问题变为:将std::vector受益于C ++的等价物realloc,它在(或多或少)已经在这里得到了回答:
当容量增加时std :: vector是否具有移动对象的能力?或者,分配器可以“重新分配”吗?
可悲的是,答案似乎是“是,但是标准委员会没有投票赞成”。希望如此
我正在尝试构建一个模板,让我使用可调整大小的数组.有没有办法找到sizeof(T)?我正在使用malloc而不是new,因为我想在调整数组大小的函数中使用realloc.这是我的类的构造函数,它正在收到错误:
template <class T>
set<T>::set(void) {
arr = malloc(10 * sizeof(T));
numElts = 0;
size = 10;
};
Run Code Online (Sandbox Code Playgroud)
尝试构建时收到以下错误消息:
error C2440: '=' : cannot convert from 'void *' to 'int *'
1> Conversion from 'void*' to pointer to non-'void' requires an explicit cast
1> c:\set.cpp(42) : while compiling class template member function 'set<T>::set(void)'
1> with
1> [
1> T=int
1> ]
Run Code Online (Sandbox Code Playgroud)
在主函数中,我用它调用它:
set<int> *set1 = new set<int>();
Run Code Online (Sandbox Code Playgroud)
从我所做的研究来看,编译器似乎无法知道用于sizeof(T)的内容,因此无法编译.我怎么会这样呢?