【问题标题】:Pointer: Read Access Violation - why?指针:读取访问冲突 - 为什么?
【发布时间】:2020-04-24 10:57:03
【问题描述】:

我有一个可以在两种变体中调用的函数。 第一个工作正常,但第二个给出了读取访问冲突。

不知何故,我没有看到错误。 你看到错误了吗?

谢谢

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++;
       }
   }
}

【问题讨论】:

  • &amp;ptr 是参数的位置,而不是它的值。
  • 你不应该使用所有这些 c-cast,它们隐藏了错误
  • fwiw,你的第一个变体看起来也有点奇怪。像其他任何东西一样,指针是按值传递的,所以它并没有真正做调用者可以观察到的任何事情(除了泄漏buffer

标签: c++ pointers


【解决方案1】:
 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;,上述所有内容都将适用,即使仍然损坏也会更有意义。以上所有内容仍然适用于&amp;ptr,除了这可能不是您想要的。

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多