(是的,我知道有一个问题几乎相同的标题,但得到的答复是不能令人满意的,见下文)
编辑抱歉,原始问题没有使用编译器优化.现在已经修复了这个问题,但是为了避免琐碎的优化并且更接近我的实际用例,测试已经分成两个编译单元.
std::vector<>具有线性复杂性的构造函数在性能关键应用程序方面是一个令人讨厌的事实.考虑这个简单的代码
// compilation unit 1:
void set_v0(type*x, size_t n)
{
for(size_t i=0; i<n; ++i)
x[i] = simple_function(i);
}
// compilation unit 2:
std::vector<type> x(n); // default initialisation is wasteful
set_v0(x.data(),n); // over-writes initial values
Run Code Online (Sandbox Code Playgroud)
当构建时浪费了大量时间x.正如这个问题所探讨的那样,传统的方法似乎只是保留存储和使用push_back()来填充数据:
// compilation unit 1:
void set_v1(std::vector<type>&x, size_t n)
{
x.reserve(n);
for(size_t i=0; i<n; ++i)
x.push_back(simple_function(i));
}
// compilation unit 2:
std::vector<type> x(); x.reserve(n); // no initialisation
set_v1(x,n); // using push_back()
Run Code Online (Sandbox Code Playgroud)
然而,正如我的评论所指出的那样,push_back()本质上是缓慢的,这使得第二种方法实际上比第一种方法慢 …
我想vector<char>用作缓冲区.该接口非常适合我的需求,但由于内存已初始化,因此在将其大小调整到超出当前大小时会有性能损失.我不需要初始化,因为在任何情况下,某些第三方C函数都会覆盖数据.有没有办法或特定的分配器来避免初始化步骤?请注意,我想使用resize(),没有其他的技巧,比如reserve()和capacity(),因为我需要size()总是代表我的"缓冲"在任何时刻的有意义的大小,同时capacity()可能会比以后它的尺寸更大resize(),所以,再一次,我可以不依赖capacity()作为我的申请的重要信息.此外,矢量的(新)大小事先不知道,所以我不能使用std::array.如果vector不能以这种方式配置,我想知道我可以使用哪种容器或分配器而不是vector<char, std::alloc>.唯一的要求是vector的替代方案最多必须基于STL或Boost.我可以访问C++ 11.
在C++中,几乎没有令人信服的理由使用C数组std::vector.其中一个令人信服的原因,至少在C++ 03中,是因为不可能使用向量来分配未初始化的对象数组."填充"构造函数std::vector是:
vector(size_type count, const T& value = T())
意思是...
int* array = new array[1000000];
Run Code Online (Sandbox Code Playgroud)
可能比以下方面更有效率:
std::vector<int> v(1000000);
Run Code Online (Sandbox Code Playgroud)
...因为向量构造函数必须对整数数组进行零初始化.因此,当使用POD向量时,没有真正的等价物malloc; 你能得到的最好的是相当于calloc.
C++ 11似乎改变了这一点,其概念是"值初始化".在C++ 11中,std::vector有一个新的构造函数,它接受一个size_type值,没有默认参数.这个"初始化"向量中的所有元素.C++ 11标准区分"值初始化"和"零初始化".
我的理解是"值初始化"等同于调用默认构造函数T.如果T是POD类型int,则默认构造函数只是创建一个未初始化的整数.因此,在C++ 11中,explicit vector::vector(size_type count)真正等同于mallocif T是POD.
但是,我对此的理解是基于C++ 11标准草案,而不是最终标准.
问题:我的理解是否正确?如果是POD,是否explicit vector::vector(size_type count)提供未初始化的数组(类似于malloc)T?
我没有得到以下声明会做什么(特别是第二行)?
auto buff = std::make_unique<int[]>(128);
buff = std::make_unique<int[]>(512);
Run Code Online (Sandbox Code Playgroud)
第二次调用make_unique后跟赋值运算符将取消分配第一次调用分配的内存,还是会出现内存泄漏?我必须要用buff.reset(new int[512]);吗?
我调试了它,但没有找到任何operator=被调用,也没有调用任何析构函数(by unique_ptr).
这是相当牵强的,但以下代码是"安全的"(即保证不会导致分段错误):
std::vector<int> vec(1); // Ensures that &vec[0] is valid
vec.reserve(100);
memset(&vec[0], 0x123, sizeof(int)*100); // Safe?
Run Code Online (Sandbox Code Playgroud)
我意识到这很难看 - 我只想知道它是否技术上安全,而不是"漂亮".我猜它唯一的用法可能是忽略存储在给定索引之外的值.
注意!如何获取vector :: reserve()分配的缓冲区地址?涵盖相同的主题,但我更感兴趣的是,如果这是安全的,如果有这样的陷阱.
编辑:原代码是错误的,取代原来memcpy用memset.
std::unique_ptr<int[]> p(new int[10]); //ok
std::shared_ptr<int[]> p(new int[10]); //Error
shared_ptr<int> sp( new int[10],[](int *p){delete [] p;});
//Ok, writing custom deleter for
//array since shared_ptr will call
//delete by default.
Run Code Online (Sandbox Code Playgroud)
与unique_ptr相比,对于数组,shared_ptr签名是否有任何特殊原因?
如果两个api都遵循类似的签名,那会更简单.
我的班级有这个成员:
static std::unique_ptr<std::unique_ptr<ICommand>[]> changestatecommands;
Run Code Online (Sandbox Code Playgroud)
我找不到初始化它的正确方法。我希望数组被初始化,但元素未初始化,所以我可以随时编写如下内容:
changestatecommands[i] = std::make_unique<ICommand>();
Run Code Online (Sandbox Code Playgroud)
数组是在声明时立即初始化还是在运行时稍后初始化都没有关系。最理想的是,我想知道如何做到这两点。
我想包装几个C函数以保证C++的安全使用.有一个C函数,它接受指向数组的原始指针及其大小,如 -
void function(char* bufferToFill, size_t bufsize)
Run Code Online (Sandbox Code Playgroud)
现在,我无法找到可以公开原始指针传递给这种函数的C++对象.我想避免使用new []并且每次抛出异常时都要记住删除[]它.
std :: string显然无法暴露它的char*,std :: vector类似,我脑海中唯一想到的是std :: unique_ptr,但它感觉有点奇怪(因为它通常用于拥有一个对象,而不是数组?)
什么是正确的C++方法来解决这样的问题?提前致谢
我知道数组需要有一个const int来初始化,所以我在main中有这个.我想要这个主要是因为我希望能够在必要时轻松修改这些数字.
const int magicWordCount = 10;
compareWords(magicWordCount);
Run Code Online (Sandbox Code Playgroud)
该功能的声明是:
void compareWords(const int);
Run Code Online (Sandbox Code Playgroud)
定义:
void Words::compareWords(const int magicWordCount)
{
std::string magic[magicWordCount] = {};
convertToStringArray(magicBuffer, magicBufferLength);
}
Run Code Online (Sandbox Code Playgroud)
当我这样做时,intellisense告诉我,定义中的"magicWordCount"下划线,表达式必须具有常量值.我对这个值不恒定的地方感到困惑.思考?
我曾经用新的方式在我的C++项目中分配内存
char* buffer = new char [size];
...
delete[] buffer;
Run Code Online (Sandbox Code Playgroud)
我真的很想继续前进并使用unique_ptr,就像这样
unique_ptr<char[]>buffer(new char[size]);
Run Code Online (Sandbox Code Playgroud)
但后来我用istream& get (char* s, streamsize n);它char*作为第一个参数,所以我该怎么办?我试过投射类型,但失败了.我也知道我可以使用vector<char>而不是指针,但我真的不想使用它.谢谢!
我想要一个具有成员数组的类.初始化对象时应该给出数组的大小.我刚刚找到了一种方法来指导这样做.我认为它工作正常,但是你可以告诉我这是否是最好的方法,或者有什么东西不起作用我还没有认识到呢?
#include <iostream>
using namespace std;
class Surface {
private:
float dx;
int N;
float* mesh_points;
public:
Surface(float, int);
~Surface();
void set_dx (float);
float get_dx();
};
Surface::Surface(float dx,int N){
this->dx = dx;
this ->N = N;
mesh_points = new float[N];
}
void Surface::set_dx (float dx) {
this->dx = dx;
}
float Surface::get_dx (void) {
return dx;
}
Surface::~Surface(){
delete[] mesh_points;
}
int main () {
Surface s(1.2,10);
s.set_dx (3.3);
cout << "dx: "<< s.get_dx() <<endl;
float mesh_points[3];
return 0;
}
Run Code Online (Sandbox Code Playgroud) c++ ×11
c++11 ×5
unique-ptr ×4
arrays ×2
c++14 ×2
pointers ×2
vector ×2
boost ×1
containers ×1
memory ×1
memory-leaks ×1
raii ×1
shared-ptr ×1
stl ×1