【问题标题】:EXC_BAD_ACESS at runtime during a pointer conversion指针转换期间运行时的 EXC_BAD_ACES
【发布时间】:2011-12-05 22:07:43
【问题描述】:

我试图在这里找到错误,调试器停止在以下位置:

Pthread_create renderer passed

Renderer loop (re)started

Process 84779 stopped

* thread #4: tid = 0x3603, 0x0000000101546c4b libjess.so`render_deformation + 667 at renderer.c:472, stop reason = EXC_BAD_ACCESS (code=1, address=0x36f0000)

    frame #0: 0x0000000101546c4b libjess.so`render_deformation + 667 at renderer.c:472

   469         for (i = 0; i < resy*resx; i++)

   470       {

   471         aux  =  (unsigned char *) ((*(tab1) << 2 ) + (unsigned int) buffer);

-> 472         *pix = *(aux) ;

   473         pix++;

   474         *pix = *(aux + 1);  
   475         pix++;

我怀疑它与指针转换有关。谁能告诉我最好的投射方式。

函数的完整代码(根据要求):

void render_deformation(int defmode)
{
   unsigned int bmax, *tab1, *tab2, *tab3, *tab4, i;
   unsigned char *pix = pixel , *buf = buffer, *aux;


   SDL_LockSurface(screen);

   /**************** BUFFER DEFORMATION ****************/



   if (video == 8)
     {
       buf = buffer;
       tab1 = table1;
       tab2 = table2;
       tab3 = table3;
       tab4 = table4;
       bmax = resx * resy + (unsigned int) pixel;

       switch(defmode)
     {
     case 0:
       memcpy(pixel,buffer,resx * resy);
       break;
     case 1:
       for (pix = pixel; pix < (unsigned char *) bmax ; pix++)
         *pix = *(buffer + *(tab1++)) ;
       break;
     case 2:
       for (pix = pixel; pix < (unsigned char *) bmax; pix++)
         *pix = *(buffer + *(tab2++)) ;
       break;
     case 3:
       for (pix = pixel; pix < (unsigned char *) bmax; pix++)
         *pix = *(buffer + *(tab3++)) ;
       break;
     case 4:
       for (pix = pixel; pix < (unsigned char *) bmax; pix++)
         *pix = *(buffer + *(tab4++)) ;
       break;   
     default:
       printf("Problem with blur_mode\n");
     }
     }
   else
     {
       pix = pixel;

       bmax = resx * resy;
       switch(defmode)
     {
     case 0:
       memcpy(pixel, buffer, pitch * resy);
       goto nodef;
       break;
     case 1:
       tab1 = table1;
       break;
     case 2:
       tab1 = table2;
       break;
     case 3:
       tab1 = table3;
       break;
     case 4:
       tab1 = table4;
       break;

     default:
       printf("Problem with blur_mode\n");
     }
       for (i = 0; i < resy*resx; i++)
     {
       aux  =  (unsigned char *) ((*(tab1) << 2 ) + (unsigned int) buffer);
       *pix = *(aux) ;
       pix++;
       *pix = *(aux + 1);  
       pix++;
       *pix = *(aux + 2);  
       pix+=2;
       tab1++;
     }
       nodef:;

     }


   SDL_UnlockSurface(screen);
}

【问题讨论】:

  • 等等,你要取消引用aux,这是一个unsigned char

标签: c macos lldb


【解决方案1】:
aux = (unsigned char ) (((tab1) << 2 ) + (unsigned int) buffer);

我的猜测应该是:

aux = (unsigned char *) (((tab1) << 2 ) + (unsigned int) buffer);

255 对于指针来说是一个非常小的值或范围...

但需要更多代码,至少需要整个函数加上相关的定义/声明(什么是“缓冲区”?为什么要转换为 unsigned int?)。

更新 111206:

类似的情况似乎是

bmax = resx * resy + (unsigned int) pixel;

应该是这样的:

bmax = resx * resy + (unsigned int*) pixel;

还有:

aux  =  (unsigned char *) ((*(tab1) << 2 ) + (unsigned int) buffer);

应该是这样的

aux  =  (unsigned char) ((*(tab1) << 2 ) + (unsigned int*) buffer);

或:

aux  =  (unsigned char*) ((*(tab1) << 2 ) + (unsigned int) buffer);

这都是基本的指针运算:它要么是 pointer := pointer + scalar; 要么是 pointer = scalar + pointer; ,但 pointer := pointer + pointer; 没有意义。第一个变体是最可能的变体(否则就不需要强制转换了)。

不确定类型的大小,但它们至少应该是指针。

仍然涉及一些错误的输入:

for (pix = pixel; pix < (unsigned char *) bmax ; pix++) {...}

像素和像素是char*; bmax 是一个无符号整数;演员很臭。我希望是这样的:

for (pix = pixel; pix < pixel+bmax ; pix++) {...}

,并且可能甚至应该将限制 (bmax) 乘以 4,以便为每个单元格颜色空间提供 24+8 位。

【讨论】:

  • 我已经添加了函数的完整代码。希望它能解决你所有的疑问。我也收到来自编译器的以下警告。 '代码renderer.c:471:警告:从指针转换为不同大小的整数renderer.c:471:警告:从不同大小的整数转换为指针。'第 471 行是 aux = (unsigned char *) ((*(tab1)
  • 非常感谢您的友好回复。我不认为这些行会导致程序崩溃。我已将问题隔离到 *pix = *(aux) ; (以及其他两条类似的行,例如 (*pix = *(aux + 1); & *pix = *(aux + 2); )当用 unsigned int 替换 aux 时,我能够正常运行,但是它不能正常工作:( 。我还想补充一点,这段代码在 Linux 系统上运行良好(原样)。我不知道 Mac OS X 在这里做了什么不同。
  • 我确实认为这些行会造成麻烦。此外,它们表明编写代码的人不知道 C。这种错误看起来像是从书中打出来的,并且在编译时进行了更正,直到它编译时禁用(或忽略)警告。
  • 那么您对此有何建设性意见?
【解决方案2】:

可能发生的情况是,在第 472 行和第 474 行,您将数据从 aux 指向的地址存储到 pix 指向的内存地址,但您的进程无法访问其中一个或两个地址。确保您正确分配了该内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-14
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 2021-01-09
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多