Указатель: нарушение прав доступа - почему? - PullRequest
0 голосов
/ 24 апреля 2020

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

Почему-то я не вижу ошибки. Вы видите ошибку?

Спасибо

void doSth(uchar *ptr, uint size, bool variant_one)
{
   uchar *buffer = new uchar[size];

   // Works
   if(variant_one) {
       for(uint i=0; i<size; i++) {
           buffer[i] = (*(ptr+1));
           ptr = ptr+2;
       }
   }
   else {
       uint16_t* ptr16 = (uint16_t*) &ptr;
       for(uint i=0; i<size; i++) {
           buffer[i] =(uchar) *(ptr16)>>4; // Gives Read Access Violation
           ptr16++;
       }
   }
}

1 Ответ

3 голосов
/ 24 апреля 2020
 uint16_t* ptr16 = (uint16_t*) &ptr;

Вы переинтерпретируете ptr как указатель на uint16_t, но такого объекта по этому адресу не существует. Попытка доступа к несуществующему объекту приводит к неопределенному поведению (по крайней мере, до C ++ 20; в некоторых случаях оно создает неявное создание тривиальных объектов).

uint16_t* ptr16 = (uint16_t*) &ptr;
   for(uint i=0; i<size; i++) {
       buffer[i] =(uchar) *(ptr16)>>4;
       ptr16++;

Предполагается, что uchar имеет ширину 8 бит типа, нет никакого способа, которым массив size 8-битных объектов будет соответствовать size числу 16-битных объектов. Вы переполняете массив.

Редактировать: все вышеперечисленное применимо, если бы вы написали (uint16_t*) ptr;, что имело бы немного больше смысла, даже если все еще не работает. Все вышеперечисленное относится и к &ptr, за исключением того, что это, вероятно, не то, что вы хотели.

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