指针递增运算符错误

发布于 2024-09-30 11:07:15 字数 1575 浏览 2 评论 0原文

好吧,这让我真的很困惑。 我正在解决一个硬件问题,并发现了一些对我来说非常奇怪的事情。 这是有问题的函数和调用

int find_oldest_frame(int **a, int size)
{
   int min = clock();
   int **ptr;
   int *ptr2;
   int frame = 0;
   int i;
   // get address of pointer so we can modify it
   ptr = a;
   // store off original pointer location.
   ptr2 = *a;

   for (i=0; i<size; i++)
   {

      // Who is the oldest time
      if (**ptr < min)
      {
         min = **ptr;
         frame = i;
      }
      printf("Current_Pointer %d\n", *ptr);
      *ptr++; // For some reason ++ doesn't work.

   }
   // now store the oldest frame with the current system time, so it's no longer the oldest.
   *ptr = ptr2;
   *ptr += frame;
   **ptr = clock();
   *ptr = ptr2;
   // Return the array index so that we can change the right page!
   return frame;

}

因此,长话短说,我收到一个弹出窗口(在 Windows 中),提示存在问题并且必须关闭。

当我尝试更换时 *ptr++; 和 *ptr+=1;

程序运行。 这引起了我的兴趣,所以我在 gcc 中使用了 -S 使用 *ptr++ 版本我得到这个指令:

addl    $4, -20(%ebp)

使用 *p+=1 我得到

movl    -20(%ebp), %eax
movl    (%eax), %eax
leal    4(%eax), %edx
movl    -20(%ebp), %eax
movl    %edx, (%eax)

这对我来说看起来是一个非常相似的操作,所以假设我正确地阅读了这个,

案例 1

增量 -20(%ebp) by 4 (假设 $4意味着)

情况2

我们将ebp中的内容存储到eax中,

(不确定()做什么),但是再做一次?

然后将 eax 偏移量 4 的地址加载到 edx 中,

现在再次将 ebp 复制回 eax 中,

现在将 edx 复制到 eax 中,

我的意思是看起来他们在做同样的事情,但由于某种原因 *ptr++ != * ptr+=1

为什么?我从我所看到的中错过了什么?

编辑:谢谢大家,现在我感觉很特别,我不敢相信我没有意识到这一点!

Ok so this one has me really confused.
I'm working on a HW problem, and discovered something that was really weird to me.
here is the function and call in question

int find_oldest_frame(int **a, int size)
{
   int min = clock();
   int **ptr;
   int *ptr2;
   int frame = 0;
   int i;
   // get address of pointer so we can modify it
   ptr = a;
   // store off original pointer location.
   ptr2 = *a;

   for (i=0; i<size; i++)
   {

      // Who is the oldest time
      if (**ptr < min)
      {
         min = **ptr;
         frame = i;
      }
      printf("Current_Pointer %d\n", *ptr);
      *ptr++; // For some reason ++ doesn't work.

   }
   // now store the oldest frame with the current system time, so it's no longer the oldest.
   *ptr = ptr2;
   *ptr += frame;
   **ptr = clock();
   *ptr = ptr2;
   // Return the array index so that we can change the right page!
   return frame;

}

So to make a long story short, I get a popup (in windows) that says there was a problem and has to close.

When I try replacing
*ptr++;
with
*ptr+=1;

The program runs.
This got me interested so I used -S in gcc
With the *ptr++ version I get this instruction:

addl    $4, -20(%ebp)

with *p+=1 I get

movl    -20(%ebp), %eax
movl    (%eax), %eax
leal    4(%eax), %edx
movl    -20(%ebp), %eax
movl    %edx, (%eax)

Which to me looks like a very similar operation, so assuming I'm reading this correctly,

case 1

Increment -20(%ebp) by 4 (assuming $4 means that)

case 2

we store what is in ebp to eax,

(not sure what () do), but do it again?

then take and load the address from eax offset by 4 into edx,

now copy ebp back into eax again,

now copy edx into eax,

I mean it looks like they're doing the same thing, but for some reason *ptr++ != *ptr+=1

Why? What am I missing from what I see?

EDIT: THANKS Everyone now I feel special, I can't believe I didn't realize that!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

锦上情书 2024-10-07 11:07:15

这实际上是运算符优先级的问题。后缀增量运算符在指针取消引用之前应用,这意味着您递增指针的值(它指向的内存),然后尝试取消引用它。这会调用未定义的行为,因为它指向单个 int

在后一种情况下,+= 在取消引用发生之后应用,因此您可以获得存储在指针内存中的值,然后添加到该值。如果您想使用后缀增量,您需要确保首先发生取消引用,您可以通过使用:

(*ptr)++;

而不是当前拥有的来实现。

This is actually an issue with the operator precedence. The postfix increment operator gets applied before the pointer is dereferenced, meaning that you increment the value of the pointer (the memory it points to) and then attempt to dereference it. This is invoking undefined behaviour since it points to a single int.

In the latter case, the += is applied after the dereference occurs, so you get the value stored at the pointer's memory, then you add to it. You need to make sure the dereference occurs first if you want to use postfix increment, which you can do by using:

(*ptr)++;

instead of what you currently have.

过去的过去 2024-10-07 11:07:15

*ptr++; // For some reason ++ doesn't work.

应该是

 (*ptr)++;

运算符优先级问题 - *ptr++ 的工作方式如下:*(ptr++) - 与

 while( ( *t++ = *s++ ) != 0 );

复制以 null 结尾的字符串相同的方式。

This

*ptr++; // For some reason ++ doesn't work.

should be

 (*ptr)++;

Operator precedence matters here - *ptr++ works this way: *(ptr++) - the same way as

 while( ( *t++ = *s++ ) != 0 );

copies a null-terminated string.

转身以后 2024-10-07 11:07:15

运算符优先级不一样。它们分别相当于:

*(ptr++);

和:

(*ptr) += 1;

您可以执行 *(ptr)++; 来增加指向的值并保持指针本身不变。

The operator precedence is not the same. They are respectively equivalent to:

*(ptr++);

And:

(*ptr) += 1;

You can do *(ptr)++; to increment the pointed value and leave the pointer itself untouched.

无人接听 2024-10-07 11:07:15

++ 运算符的优先级高于*,其优先级高于+=++ 绑定到 ptr,而 += 绑定到 (*ptr)

The ++ operator has higher precedence than *, which has higher precedence than +=. The ++ binds to ptr, while the += binds to (*ptr).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文