C ++: получить адрес начала std :: vector? - PullRequest
6 голосов
/ 28 апреля 2010

Иногда полезно использовать начальный адрес std::vector и временно рассматривать этот адрес как адрес регулярно выделяемого буфера.
Например, замените это:

 char* buf = new char[size];
 fillTheBuffer(buf, size);
 useTheBuffer(buf, size);
 delete[] buf;

С этим:

 vector<char> buf(size);
 fillTheBuffer(&buf[0], size);
 useTheBuffer(&buf[0], size);

Преимущество этого, конечно, в том, что буфер освобождается автоматически, и мне не нужно беспокоиться о delete[].

Проблема, с которой я сталкиваюсь, это когда размер == 0. В этом случае первая версия работает нормально. Пустой буфер «выделяется», и последующие функции ничего не делают размер, который они получают размер == 0.
Однако вторая версия дает сбой, если size == 0, так как вызов buf[0] может справедливо содержать утверждение, что 0 < size.

Так есть ли альтернатива идиоме &buf[0], которая возвращает адрес начала вектора, даже если вектор пуст?

Я также рассматривал возможность использования buf.begin(), но в соответствии со стандартом даже не гарантированно возвращать указатель.

Ответы [ 4 ]

8 голосов
/ 28 апреля 2010

Полагаю, вам просто нужно проверить.

Возможно, полезная функция:

template <class T, class Alloc>
T* data(std::vector<T, Alloc>& vec)
{
    return vec.empty() ? 0 : &vec[0];
}

template <class T, class Alloc>
const T* data(const std::vector<T, Alloc>& vec)
{
    return vec.empty() ? 0 : &vec[0];
}
1 голос
/ 28 апреля 2010

Если вы можете изменить fillTheBuffer и использоватьTheTheBuffer, чтобы взять пару итераторов, то вы будете решать проблему так же, как стандартная библиотека решала ее.

1 голос
/ 28 апреля 2010

Я думаю, вы должны быть в безопасности в любом случае. Я считаю, что различия между vector :: operator [int] и vector :: at (int) в том, что перегрузка оператора [] специально не выполняет проверку границ. Использование buf [0] не должно содержать утверждений!

1 голос
/ 28 апреля 2010

Для этого нет функции, хотя std::basic_string имеет data(), которая делает именно то, что вам нужно.

Вам придется использовать что-то вроде buf.size()?&buf[0]:0;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...