C++ 指针和动态数组以及删除运算符

标签 c++ pointers dynamic-arrays delete-operator

好的,所以我要布置两个程序。两者都是使用指针和 new 运算符的动态数组。但是有人似乎不喜欢删除运算符。

#include <iostream>
int main()
{
  int *p;
  p = new int[5];

  for (int i = 0; i < 5; i++)
  {
    p[i] = 25 + (i * 10);
    std::cout << p[i] << " ";
  }
  std::cout << std::endl;

  delete [] p;
  p = NULL;

  return 0;
}

这是第一个程序。它非常喜欢删除运算符。现在不喜欢删除运算符的程序:

#include <iostream>
int main()
{
  int x;
  int *p;
  p = new int[5];

  *p = 4;

  for (int i = 0; i < 5; i++)
  {
    std::cout << *p << " ";
    x = *p;
    p++;
    *p = x + 1;
  }
  std::cout << std::endl;

  delete [] p;
  p = NULL;

  return 0;
}

这个程序编译得很好。但在执行期间,它会抛出错误 - free(): invalid pointer: 0xfdb038 .. 或该特定执行的任何内存地址。所以,问题是: 为什么不能在第二种情况下使用 delete 运算符? 我不想有内存泄漏;我不希望指针悬空。 如果我只是说 p = NULL;,那么 p = 0,但我相信指针仍然悬空?但我不确定。提前致谢。

最佳答案

看看第二段代码中的这个循环:

for (int i = 0; i < 5; i++)
{
  std::cout << *p << " ";
  x = *p;
  p++;
  *p = x + 1;   // <--- Here
}

请注意,在这一行中,您写入了当前由 p 指向的内存地址。因为您总是递增 p 然后写入它,所以您最终会在您为 p 分配的区域末尾注销。 (如果我们将 pOrig 想象成指向 p 最初指向的位置的指针,那么这将写入 pOrig[1]pOrig[2 ]pOrig[3]pOrig[4]pOrig[5],最后一次写入超过区域的末端)。这会导致未定义的行为,这意味着实际上任何事情都可能发生。这是个坏消息。

此外,delete[] 假定您传递的是指向您分配的数组的第一个元素的指针。由于您在该循环中递增了 p 多次,因此您试图 delete[] 一个不在分配数组底部的指针,因此问题。

要解决此问题,请不要在递增后写入 p,并存储指向用 new[] 分配的原始数组的指针,以便您可以释放它而不是修改后的指针 p

关于C++ 指针和动态数组以及删除运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37901560/

相关文章:

c++ - 错误 LNK2019 错误 C++

c++ - 在使用 NT DDK 构建的用户模式程序中包含 C++ header

c++ - 使用通用函数指针 C++ 传递方法所需类型的参数

C++ 矩阵到动态二维数组

c - malloc 结构中的结构数组

C++ MFC 如何将应用程序发送到托盘

c++ - 如何在 Turbo C++ 中链接多个文件?

c - 使用指向字符的常量指针时使用引用运算符与 C 中的正常初始化

c++ - 我想返回局部变量的地址

c# - 如何将结构向量从 Rust 返回到 C#?