指向栈内存的指针:内存陷阱 驯服C++中的野指针



什么是野指针?

  个母亲有两个小孩(两个指针)个在厨房个在卧室(属于区别代码块其生存期区别)母亲让在厨房小孩带块蛋糕(指针指向对象)给在卧室小孩这样在卧室孩子才肯写作业但这个在厨房小孩比较淘气他在走出厨房时自己将蛋糕吃了没能带出来而在卧室没有吃到蛋糕所以不肯完成他作业结果母亲却不知道卧室孩子没有吃到蛋糕还以为作业完了结果第 2天她就被老师召唤到办公室了事情麻烦了

  这样那个在卧室孩子就是野指针了他没有得到应得蛋糕不能完成母亲交给他作业

  这就是c中所讲野指针上面小剧本不过演示了种最基本野指针形成过程更容易出现情形是coder在编码时大意的下使用了已经free过指针

  对于年轻点经验欠缺coder来说是比较容易犯经验老到员或者慎重采取成对编程形式避免这种失误或者使用引用计数器防止形成野指针

  总的在c中野指针也许性子野但是控制起来也是有章可循然而事情在c中出现了变化

  coder们面临更大麻烦了c员无可避免要写很多这样那样谁让c是面向对象呢?

  我们在写类时候难免要用给类数据成员分配内存这本来没什么动态分配内存是种很常见基本操作我们在学数据结构时经常这么做不是么?

  但是伙计事情并非这么简单类是种高级用户自定义数据类型看起来和结构、枚举这样用户自定义类型没啥太大差别如果你这样认为....?那你会死很惨类太复杂了普通情况下使用类对象并没有太大问题但是当你要复制个对象时问题就来了

  比如我们知道你要用个对象化另个对象时c是按位进行拷贝即在目标对象里创建了化对象个完全相同拷贝这在多数情况下已经足够了但是当你类在创建时为每个对象分配内存也就是说类中有操作当你对象创建好后类也为对象分配了块内存如果你用这个对象去化另个对象时对象和对象完全这意味着他们使用同块内存而不是重新为被对象分配内存

  这样麻烦就大了如果个对象销毁了那么分配内存也就销毁了(别忘了类是有析构它负责在对象销毁时释放动态分配内存难道你说你不在类中写上析构部分?那么可怜孩子那你就走向了另个深渊当你运行数小时的后系统会告诉你内存不够用了想象下把你用在腾讯服务器上)个对象就残缺不全了这就像对连体婴儿他们共用了部分器官心脏或者肝脏要救活就牺牲了另个得病了个也要遭殃

  可以说这就是c中更加变态野指针

  什么?你说我不用对象化对象?那么我们会不会将个对象作为变元传递给呢?我们很多时候都这样做有时我们不得不将对象按值传递给但是你要知道按值传递是什么意思?它意思就是把实参个拷贝传递给这和刚才化没什么两样按位拷贝体内对象和外面对象共用块内存即便在对象没有对这块内存进行过操作但是当结束时析构将会被......

  还有种和的相反情况...... 当你想要把个在对象值返回给外面对象时这时候会自动产生个临时对象由它容纳返回值并在结束时把结果传给目标那么这个临时对象迅速被创建并被迅速释放块内存被释放了两次其后果是不可预见

  当你把个对象值赋给另个对象时如果你没有重载赋值运算符那么也会导致按位拷贝最终产生个野指针(个隐藏在类内毒瘤)或者释放同块内存多次

  看到了么?害怕了么?是不是感到c到处都是陷阱呢?不但有陷阱到处都是危险品所有c中疑难问题到了c就成了般问题了好了不废话了我们继续讲讲解决的道

  对于最后这种赋值情况我们只有通过重载赋值运算符才能解决也就是避免按位拷贝

  至于前面都属于概括下来就是 3种情况:

  1.当个对象化另个对象时例如在声明中;

  2.把所创建对象拷贝(按值)传递给时;

  3.生成临时对象时最常见就是返回值

  解决化时按位拷贝问题我们通过创建拷贝构造来解决

  基本拷贝构造形式为:
代码:
name (const name &o) 

//body here 
}
  拷贝构造就是针对这个问题而设计

  恩大家都明白了吧?不要让你对象都变成可怜连体人啊~~~~
Tags:  野指针 指向栈内存的指针

延伸阅读

最新评论

发表评论