C++ новое выделение массива C, RAII или простой shared_ptr / boost::shared_array

Я изучаю с ++, и я наткнулся еще раз на новую проблему.

Мне нужно выделить массив C для библиотеки для использования, но безопасным способом, конечно. Я уже обнаружил, что delete[]; в конце метод с треском проваливается.

СТАРЫЙ, не очень хорошо

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 сейчас?!

если я выделю shared_ptr в новой области видимости {} после того, как новая будет уничтожена... Объясните мне и новичкам, таким как я, в будущем немного больше. Как обрабатывать исключения в этом случае?

1 ответ

Решение

Предпочитать 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*`

* не используйте std::vector если код C когда-либо "перераспределит" указатель для вас. Вместо этого используйте std::unique_ptrи (1) освободить память, (2) передать C, (3) сбросить с указателем, возвращенным из C.

Другие вопросы по тегам