删除和无效指针

时间:2014-07-02 04:09:41

标签: c++ memory glibc delete-operator

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[]。但是在这种情况下,为什么要删除所有元素呢?

2 个答案:

答案 0 :(得分:4)

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

  1. 空指针值。他们只是被忽略了。
  2. 以前使用new分配的完整标量(非数组)对象,可以是:
    • new
    • 返回的确切指针
    • 指向new返回的指针的基础子对象的指针,当且仅当基础子对象的类型具有virtual析构函数
  3. 任何这些指针值都不应该传递给标量delete

    1. 数组newnew[]的结果(改为使用delete[]
    2. malloc或任何其他非new
    3. 分配器的结果
    4. 具有自动或静态存储持续时间的对象的地址
    5. 成员子对象或数组元素的地址
    6. 未初始化的指针值
    7. 指向已删除对象的指针
    8. 如果您违反此规则,则会获得未定义的行为。这意味着您的程序可能会崩溃,并显示一条消息,指出检测到无效删除。或者您的数据可能已损坏,保存在数据文件中,发送给您的老板,显示给客户,之后您会被解雇。所以不要违反规则。

      您的代码属于类别&#34;从不这样做#4&#34;。


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

答案 1 :(得分:1)

  1. 没有。 deletenew相反。您基本上删除分配时获得的相同指针。删除其他指针是未定义的,因此您的“无效指针”错误。如果您分配了一个数组,则必须使用delete[]。现在,你正在泄漏(“没有释放”)那个记忆。完成后请使用delete [] a;

  2. 不太适用。

  3. 因为这就是C ++的工作方式。它是用于释放您分配的数组的操作。

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

    cout << a;
    

    代替。