Преобразование (void *) в std :: vector

Глядя на исходный код Throwable :

  187       /**
  188        * The throwable that caused this throwable to get thrown, or null if this
  189        * throwable was not caused by another throwable, or if the causative
  190        * throwable is unknown.  If this field is equal to this throwable itself,
  191        * it indicates that the cause of this throwable has not yet been
  192        * initialized.
  193        *
  194        * @serial
  195        * @since 1.4
  196        */
  197       private Throwable cause = this;

Итак, я думаю, что то, что вы видите, является Исключением, которое было создано без использования одного из конструкторов, который принимает Причина.

Вы увидите это в отладчике, но getCause не заботится о возврате рекурсивной ссылки:

  414       public synchronized Throwable getCause() {
  415           return (cause==this ? null : cause);
  416       }

13
задан Mike Douglas 7 April 2009 в 10:43
поделиться

4 ответа

Вам будет нужна длина буфера. После того как Вы делаете, мы можем сделать это:

unsigned char *charBuf = (unsigned char*)voidBuf;
/* create a vector by copying out the contents of charBuf */
std::vector<unsigned char> v(charBuf, charBuf + len);

Хорошо, комментарий запустил меня на том, почему я не использовал reinterpret_cast:

  • В C++ бросок C-стиля является функцией удобства - он просит, чтобы компилятор выбрал самое безопасное и большую часть портативной формы преобразования по набору доступных операторов броска.

  • reinterpret_cast определенная реализация и должна всегда быть последняя вещь на Вашем уме (и используемый, когда Вы обязательно делаете непортативную вещь сознательно).

  • Преобразование между (unsigned не изменяет тип), char * и void * является портативным (Вы могли на самом деле использовать static_cast если Вы действительно придирчивы).

Проблема с броском C-стиля: добавленная гибкость может вызвать страдания, когда тип указателя изменяется.

Примечание: Я соглашаюсь с общей конвенцией не кастинга как можно больше. Однако без любого источника, если, это является лучшим, я мог сделать.

27
ответ дан 1 December 2019 в 07:40
поделиться

Вы не можете просто бросить a void* к a std::vector<unsigned char> потому что расположение памяти последнего включает другие объекты, такие как размер и число байтов, в настоящее время выделяемых.

Принятием буфера указывают buf и его длина n:

vector<unsigned char> vuc(static_cast<char*>(buf), static_cast<char*>(buf) + n);

создаст копию буфера, который можно безопасно использовать.

[РЕДАКТИРОВАНИЕ: Добавленный static_cast<char*>, который необходим для адресной арифметики с указателями.]

3
ответ дан 1 December 2019 в 07:40
поделиться

Единственное время это было бы законно, - то, если Вы уже создали вектор и просто хотели вернуть его.

void SomeFunc(void* input);

main() {
  std::vector< unsigned char > v;
  SomeFunc((void*) &v);
}

SomeFunc(void* input) {
  // Now, you could cast that void* into a vector
  std::vector< unsigned char >* v_ = (vector<unsigned char>*)input
}

Я на самом деле не попытался видеть, будет ли это работать, но это - дух его. Тем не менее при создании этого с нуля Вы определенно делаете его неправильно. Это действительно плохо. Единственное время это могло быть даже удаленно понятно, - то, если Вы вынуждены реализовать уже определенный "SomeFunc ()".

3
ответ дан 1 December 2019 в 07:40
поделиться

использование станд.:: векторный класс для уже выделенного буфера не является решением. Станд.:: векторный объект управляет памятью и освобождает ее во время разрушения.

Сложное решение могло бы состоять в том, чтобы записать Ваше собственное средство выделения, которое использует уже выделенный буфер, но необходимо быть очень осторожными на нескольких сценариях, как векторное изменение размеров, и т.д.

Если у Вас есть та пустота* буфер, связанный через некоторые API-функции C, то можно забыть о преобразовании в станд.:: вектор.

При необходимости только в копии того буфера она может быть сделана как это:

std::vector< unsigned char> cpy( 
    (unsigned char*)buffer, (unsigned char*)buffer + bufferSize);

где bufferSize является размером в символах скопированного буфера.

2
ответ дан 1 December 2019 в 07:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: