【问题标题】:Delete and invalid pointer删除和无效指针
【发布时间】:2014-08-22 17:57:19
【问题描述】:
int main()
{
    char* a=new char[20];  
    cin>>a;  
    cout<<" character at 7-th position."<<a[6];  
    delete a+4;  
    cout<<a[0];
    return 0;
}

输入:

1234567894567 

输出:

character at 7-th position.6  
*** glibc detected *** ./test free() invalid pointer:....  

现在我有 3 个问题

  1. delete a+4 只会删除a+4 处的字符是否正确?
  2. 如果对前一个的回答是肯定的,那么a[0] 会发生什么。我们应该得到输出。
  3. 要删除一块内存,我们应该写delete[]。但是在这种情况下,为什么所有的元素都被删除了?

【问题讨论】:

  • 你不能“删除一个字符”。
  • 那我怎样才能找回那段记忆呢??
  • 我们可能应该对“C++ 删除运算符可以使用哪些指针值?”有一个规范的答案
  • 呃,删除字符数组。你特别说“要删除一块内存,我们应该写 delete[]”。是的,这个。
  • 当我要删除 a+4 时,内存已损坏,然后我们无法访问同一块的任何元素。是这样吗??

标签: c++ memory glibc delete-operator


【解决方案1】:

只有三种类型的指针值可以作为delete 的操作数传递:

  1. 空指针值。他们只是被忽略了。
  2. 以前使用new 分配的完整标量(非数组)对象,可以是:
    • new 返回的确切指针
    • 指向new 返回的指针的基子对象的指针,当且仅当基子对象的类型具有virtual 析构函数时

任何这些指针值都不应该被传递给标量delete

  1. 数组newnew[]的结果(使用delete[]代替)
  2. malloc 或任何其他不是new 的分配器的结果
  3. 具有自动或静态存储持续时间的对象的地址
  4. 成员子对象或数组元素的地址
  5. 未初始化的指针值
  6. 指向已删除对象的指针

如果你违反了这条规则,你会得到未定义的行为。这意味着您的程序可能会崩溃,并显示检测到无效删除的好消息。或者您的数据可能会损坏,保存在您的数据文件中,发送给您的老板,展示给客户,然后您会被解雇。所以不要违反规则。

您的代码属于“永远不要这样做 #4”类别。


它以这种方式工作的原因是因为实现可以(并且大多数都可以)跟踪称为元数据的额外信息以及每个分配的块。例如,块的大小,这对于实现重用非常重要。块的一部分没有元数据,可能没有办法从指针到中间找到元数据。

【讨论】:

  • 如果这开始成为一个规范问题,我很乐意添加标准中的引号。
【解决方案2】:
  1. 没有。 deletenew 相反。您实际上删除了分配时获得的相同指针。删除其他指针是未定义的,因此您的“无效指针”错误。如果你分配了一个数组,你必须使用delete[]。现在,您正在泄漏(“未释放”)该内存。所以完成后使用delete [] a;

  2. 不太适用。

  3. 因为这就是 C++ 的工作原理。这是你用来释放你分配的数组的操作。

出现您想从字符串中删除一个字符,然后打印该字符串。如果这是您所追求的,请考虑使用std::string 并使用其remove 成员函数。无论如何,a[0]char,而不是 char*,后者是 C 风格的字符串。你应该

cout << a;

改为。

【讨论】:

  • 谢谢..但我无法理解你答案的最后一行。你应该是什么意思......我的意思是你说如果你不想打印一个字符串那么做 cout
  • 如果要打印字符串,而不是单个字符,则将指针传递给第一个字符并打印,直到找到空字节(字符串标记的结尾)。如果您只想打印一个字符,那么您做对了。
  • 很高兴为您提供帮助。祝你好运。
猜你喜欢
  • 1970-01-01
  • 2011-08-21
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 2012-07-23
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多