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

时间:2016-06-18 20:58:13

标签: 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 ..或者该特定执行的内存地址。所以,问题是: 为什么在第二种情况下不能使用删除操作符? 我不想让内存泄漏;我不希望指针悬空。 如果我只是说p = NULL;,然后是p = 0,但我相信指针仍悬着?,但我不确定。提前谢谢。

3 个答案:

答案 0 :(得分:2)

在第二段代码中查看此循环:

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[]的原始数组的指针,以便您可以释放它而不是修改后的指针{ {1}}。

答案 1 :(得分:0)

您必须grecaptcha.reset(); delete获得的指针。但是,在您的第二个代码中,您执行了更改指针的new。因此,您尝试p++deletenew崩溃中获得的指针。

要解决此类错误,请不要使用delete。而是使用new。由于您永远不需要std::vector<int> p;,因此您无法忘记new

答案 2 :(得分:0)

p中的问题正在改变p++。 您应该始终存储(删除)原始指针。像这样:

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

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

  delete [] original;    
  return 0;
}