2017-09-26 34 views
-8

我不明白为什么当我们删除一个指向另一个对象的指针时,PC会爆炸。我不明白到底发生了什么事。指向另一个对象后删除指针会产生运行时错误

我故意创建这个错误,以了解发生了什么。


Rule.h
#ifndef RULE_H 
#define RULE_H 

#include <iostream> 
#include <ostream> 

class Rule{ 

    friend std::ostream & operator<<(std::ostream & output, const Rule &); 
public: 
     Rule(); 
     ~Rule(); 
     //I remove copy constructo and assignment operator for clarity 
     void insert_num(const int &); 
private: 
    int _num; 
    int *_numbers; 
    int _used; 
}; 

#endif 

Rule.cpp
#include "Rule.h" 

#include <iostream> 
#include <ostream> 

Rule::Rule():_numbers(new int[100]),_used(0){} 

Rule::~Rule(){ 
    std::cout << "Destructor called " << std::endl; 
    delete [] _numbers; 
} 

void Rule::insert_num(const int & x){ 
    if(_used == 100){ 
     std::cout <<"cannot add more number " << std::endl; 
    } 
    else{ 
     _numbers[_used] = x; 
     _used += 1; 
    } 
} 

main.cpp中
#include "Rule.h" 

#include <iostream> 

int main(){ 
    Rule rule1; 
    rule1.insert_num(1); 

    Rule *rule4 = new Rule(); 
    rule4->insert_num(9); 

    rule4 = &rule1; 

    delete rule4; 
} 

错误

00400000-00402000 R-XP 00000000 08:08 9699974
/家庭/ hanidaher /工作区/ CPLUSPLUS/rule_of_three /出 00601000-00602000 [R - P 00001000 08 :08 9699974
/家庭/ hanidaher /工作区/ CPLUSPLUS/rule_of_three /出 00602000-00603000 RW-p 00002000 08:08 9699974
/家庭/ hanidaher /工作区/ CPLUSPLUS/rule_of_three /出 019a6000-019d8 000 RW-P 00000000 00:00 0
[堆] 7efca4000000-7efca4021000 RW-P 00000000 00:00 0 7efca4021000-7efca8000000 --- p 00000000 00:00 0 7efca8305000-7efca840d000 R-XP 00000000 08:07 7865590
/lib/x86_64-linux-gnu/libm-2.23.so 7efca840d000-7efca860c000 --- p 00108000 08:07 7865590
/lib/x86_64-linux-gnu/libm-2.23.so 7efca860c000-7efca860d000 R- -p 00107000 08:07 7865590
/lib/x86_64-linux-gnu/libm-2.23.so 7efca860d000-7efca860e000 RW-p 00108000 08:07 7865590
/lib/x86_64-linux-gnu/libm-2.23 .so 7efca860e000-7efca87ce000 r-xp 00000000 08:07 7865595
/lib/x86_64-linux-gnu/libc-2.23.so 7efca87ce000-7efca89ce000 --- p 001c0000 08:07 7865595
/lib/x86_64-linux-gnu/libc-2.23。所以7efca89ce000-7efca89d2000 - [R - p 001c0000 08:07 7865595
/lib/x86_64-linux-gnu/libc-2.23.so 7efca89d2000-7efca89d4000 RW-p 001c4000 08:07 7865595
/LIB/x86_64的Linux的-gnu/libc-2.23.so 7efca89d4000-7efca89d8000 rw-p 00000000 00:00 0 7efca89d8000-7efca89ee000 r-xp 00000000 08:07 7868899 /lib/x86_64-linux-gnu/libgcc_s.so.1 7efca89ee000-7efca8bed000 --- p 00016000 08:07 7868899
/lib/x86_64-linux-gnu/libgcc_s.so.1 7efca8bed000-7efca8bee000 RW-P 00015000 08:07 7868899
/lib/x86_64-linux-gnu/libgcc_s.so.1 7efca8bee000-7efca8d60000 R-XP 00000000 08:07 14951439
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0。21 7efca8d60000-7efca8f60000 --- p 00172000 08:07 14951439
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 7efca8f60000-7efca8f6a000 - [R - P 00172000 08:07 14951439
/usr/lib中/ x86_64的-Linux的GNU /的libstdC++。so.6.0.21 7efca8f6a000-7efca8f6c000 RW-p 0017c000 08:07 14951439
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21 7efca8f6c000-7efca8f70000 RW-p 00000000 00:00 0 7efca8f70000-7efca8f96000 R-XP 00000000 08:07 7865561
/lib/x86_64-linux-gnu/ld-2.23.so 7efca916e000-7efca9173000 RW-p 00000000 00:00 0 7efca9192000-7efca9195000 rw-p 00000000 00:00 0 7efca9195000-7efca9196000 - [R - P 00025000 08:07 7865561
/lib/x86_64-linux-gnu/ld-2.23.so 7efca9196000-7efca9197000 RW-P 00026000 08:07 7865561
/LIB/x86_64的-Linux的GNU/ld-2.23.so 7efca9197000-7efca9198000 RW-p 00000000 00:00 0 7fff8bacc000-7fff8baed000 RW-p 00000000 00:00 0
[堆] 7fff8bbe6000-7fff8bbe8000 - [R - p 00000000 00:00 0
[ VVAR] 7fff8bbe8000-7fff8bbea000 R-XP 00000000 00:00 0
[VDSO] ffffffffff600000-ffffffffff601000 R-XP 00000000 00:00 0
[vsyscall]

+9

你只能'删除'用'new'创建的东西。你违反了这条规则。现在你知道你为什么不应该这样做了。:-) –

+2

你问题的一半等同于'int x; int * p =&x; delete p;' – user463035818

+1

为了解释你所看到的行为,找到编译器的源代码并调试'delete'功能。考虑一下内存分配算法和相关的删除。现在使用不属于内存池一部分的局部变量调用该删除函数。 –

回答

4

在局部变量上使用delete是未定义的行为。 delete运算符用于使用new分配的动态分配对象。

允许编译器将变量存储到寄存器中,删除寄存器没有意义。

编译器可能会将变量放在堆栈上,并删除堆栈内存是没有意义的。

未定义的行为没有标准行为;任何事情都可能发生,并且不希望StackOverflow上的人员解释未定义行为的结果。

相关问题