【问题标题】:Operator precedence and pointer arithmetic运算符优先级和指针运算
【发布时间】:2013-05-26 19:12:48
【问题描述】:

给定以下代码:

void Allocate(int *p)
{
    p = new int;
    *p++ = 2;
}

int main()
{
    int i = 10;
    Allocate(&i);
    std::cout << i << std::endl;
}

我有点迷信:

*p++ = 2;

输出是10,我对为什么会出现这种情况的推理是*p++ 是一个临时的,因此在Allocate(int *p) 范围的末尾对它的任何分配都会丢失。

是这样吗? 感谢您的建议!

【问题讨论】:

  • 你在做这样的事情时应该小心。通过增加该指针,您处于未定义行为的边缘。除了将其向前移动一个位置之外的任何操作都将是未定义的行为,因为它超出了数组之外或超出了末尾,请记住,出于指针运算的目的,单个变量被视为单个元素数组。

标签: c++ pointers scope rvalue


【解决方案1】:
  • 在输入Allocate 时,p 指向main 中的变量i 功能。
  • 此变量的地址随后丢失并由 new int
  • 此 int 的值(未初始化,因此可以 start as any) 设置为 2。
  • p 指针递增。
  • Allocate 函数此时返回,泄漏了原来的 int 已分配。
  • imain函数中的值不变, 因为Allocate 没有修改它。

【讨论】:

    【解决方案2】:

    当您将 i 的地址传递给 Allocate 时,会创建另一个(临时)指针指向 i 的地址(即通过指针传递)。然后该临时指针指向一个新位置(通过新 int)。因此 i 的值是单独存在的。

    【讨论】:

    • 所以因为 Allocate(int *p) 做了一个临时副本,所以只有那个副本被处理,所以原始文件保持不变?
    • @PatMustard,是的,指针已复制,但仍指向同一位置 (&amp;i)。如果不是,您在尝试修改i 的地址时会遇到很多问题。
    • 谢谢大家的解释!
    • 鉴于上述情况,您可能会破坏您的堆栈或基指针(因为堆栈长大了)。无论哪种方式 - 都不会发生任何好事,如果您在真实代码中执行此操作,请尽情追踪错误。
    【解决方案3】:
    p = new int;
    

    您正在分配 p 新内存来指向而不是它之前指向的内容。然后,您更改了这个新分配的内存,当函数结束时它会永远丢失,从而导致内存泄漏。如果删除分配行,它会导致输出 2。在这种情况下 ++ 什么也不做。它只是增加指针并返回旧值以取消引用。

    【讨论】:

      【解决方案4】:

      一旦你输入Allocate,你就指定p指向一个新的内存块,所以它不再指向i。然后修改新的内存块(然后在方法返回时泄漏。)i 不受影响,因为您在设置指向的内存单元之前移动了该指针。

      【讨论】:

        【解决方案5】:
        void Allocate(int **p)
        {
            *p = new int;
            **p = 2;
        }
        
        
        int main()
        {
            int j = 10;
            int *i = &j;
            std::cout << i << std::endl;
            Allocate(&i);
            std::cout << i << std::endl;
        }
        

        输出是: 10 2

        你需要一个指针来改变被指向位置的地址。

        【讨论】:

          猜你喜欢
          • 2019-06-06
          • 2014-01-24
          • 2011-06-21
          • 2020-03-05
          • 1970-01-01
          • 2023-03-07
          • 1970-01-01
          • 2011-07-07
          相关资源
          最近更新 更多