我正在学习 C++,我再次偶然发现了一个新问题。
我确实需要分配一个 C 数组供库使用,但当然要以安全的方式。我已经发现删除[];在方法结束时惨遭失败。
旧的,不太好:
float *buf;
try {
buf = new float[daswidth*chans_info.chans*sizeof(float)];
}
catch (std::bad_alloc& ba) // sometimes it throws ! so i do need to stop my execution.
{
if (DEBUG) tekstasFormat(L"WARNING: bad alloc caught: %s", ba.what());
return; // skip this iteration then.
}
//... OUR CODE
delete[] buf;
所以我尝试使用它完美地代替了我旧的分配和删除:
float *buf;
std::shared_ptr<float> safe_buf(new float[daswidth*chans_info.chans*sizeof(float)], [](float *p) { delete[] p; });
// OR BOOST EQUIVALENT
boost::shared_array<float> safe_buf(new float[daswidth*chans_info.chans*sizeof(float)]);
buf = safe_buf.get();
而且我们从不泄漏,每个人都很高兴。 但现在如何捕获 new_alloc 抛出?!
如果我在 new 之后在 new{} 作用域中分配shared_ptr,它就会被破坏......向我和像我这样的菜鸟解释一下 future 的情况。 这种情况下如何处理异常?
最佳答案
优先选择std::unique_ptr
而不是shared_ptr
。速度要快得多。
std::unique_ptr<float[]> buf; //construct
try {
buf.reset(new float[daswidth*chans_info.chans*sizeof(float)]); //give memory
}
catch (std::bad_alloc& ba) // sometimes it throws ! so i do need to stop my execution.
{
if (DEBUG) tekstasFormat(L"WARNING: bad alloc caught: %s", ba.what());
return; // skip this iteration then.
}
但是,正如 Ben
所说,几乎没有理由使用这样的 float[]
。相反,请使用 std::vector
。是的,即使对于大多数* C 互操作也是如此。
std::vector<float> buf;
try {
buf.resize(daswidth*chans_info.chans*sizeof(float)); //give memory
}
catch (std::bad_alloc& ba) // sometimes it throws ! so i do need to stop my execution.
{
if (DEBUG) tekstasFormat(L"WARNING: bad alloc caught: %s", ba.what());
return; // skip this iteration then.
}
function_expecting_float_pointer(buf.data()); //use .data() to get the `float*`
*如果 C 代码会为您“重新分配”指针,则不要使用 std::vector
。相反,使用 std::unique_ptr,并且 (1) 释放内存,(2) 传递给 C,(3) 使用从 C 返回的指针重置。
关于c++ 新的 C 数组分配,RAII 或简单的shared_ptr/boost::shared_array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27629781/