24小时热门版块排行榜    

查看: 238  |  回复: 1
当前主题已经存档。

zsglly

木虫 (著名写手)

[交流] C++ Without Memory Errors(英)

by Dejan Jelović

Here are the slides and the code from a recent talk I've given on writing C++ programs without memory errors.

An article with more details will be ready soon.


--------------------------------------------------------------------------------

Memory errors are the worst kind of errors in C and C++. They are hard to reproduce and thus hard to debug. Have you ever used a non-trivial C or C++ program that never crashed?


--------------------------------------------------------------------------------

I've been programming in Java for the last year. In Java one sees almost no hard to reproduce problems. Why is that?


--------------------------------------------------------------------------------

Is it because Java is a safer language? No. Java makes you use too many casts and lacks support for types with value semantics. It doesn't have destructors so resource management is really hard. It is less safe than C++.


--------------------------------------------------------------------------------

The real reason is garbage collection.


--------------------------------------------------------------------------------

How does garbage collection help? Does it free us from freeing memory? Not really. Try implementing a Vector in Java and you will see how easy it is to forget to set a reference to null, thus leaking memory.


--------------------------------------------------------------------------------

The benefit of garbage collection is this: it guarantees that a pointer will either point to a valid allocated object or be null.


--------------------------------------------------------------------------------

Think about it: if a pointer is either valid or null, there can be no weird memory errors.


--------------------------------------------------------------------------------

How do we do that in C++?


--------------------------------------------------------------------------------

How about adding garbage collection to C++? A company named Geodesic claims their garbage collector for C++ works great.


--------------------------------------------------------------------------------

Garbage collection helps, but it is not enough. We still have to call the destructors manually, and to remember to set pointers to NULL. That's too much room for error.

There is also a performance penalty. Programs with garbage collection use 50% more memory than programs with manual memory management. That translates into much slower execution because it increases the chances of memory being swapping out to disk.


--------------------------------------------------------------------------------

Here's the solution: Use a smart pointer.


--------------------------------------------------------------------------------

What would be the characteristics of such a smart pointer?

It always points either to a valid allocated object or is NULL.  
It deletes the object once there are no more references to it.  
It can be used with existing code.  
Programs that don’t do low-level stuff can be written exclusively using this pointer. Native pointers don’t have to be used at all.  
Native pointers can be converted into smart pointers via a special construct. It should be easy to search for this construct using grep since it is unsafe.  
Thread-safe.  
Exception safe.  
Fast. It should have zero dereferencing overhead and minimal manipulation overhead.  
It shouldn’t have problems with circular references.  

--------------------------------------------------------------------------------

If we disregard the requirement #9, then it's easy. Simply have a smart pointer that is made out of two native pointers. One points to the real object, the other to the reference count:






--------------------------------------------------------------------------------

We also provide a template function called create that creates a new object using the operator new and then returns a smart pointer. That guarantees that the smart pointer is valid.  
We also provide a back door to ease the transition. There is a wrapPtr function that takes a native pointer and makes a smart pointer. This is unsafe. So we didn't use a constructor, but a special function that is easy to search for if you have any problems.


--------------------------------------------------------------------------------

This leaves us with the problem of circular references.


--------------------------------------------------------------------------------

Circular references and reference counting don't go well together. Maybe we can find a simpler problem?


--------------------------------------------------------------------------------

In real-world programs you almost never have real cyclic data structures. Usually you have hierarchies, like the window hierarchy or a directory tree:




--------------------------------------------------------------------------------

The problem with a reference counting and hierarchies is that a parent points to a child, and a child points to the parent. Hence they both have a reference count of one, and are never deleted.


--------------------------------------------------------------------------------

People that use reference-counted pointers usually find a way out of this mess by using a native pointer from the child to the parent.

But this is not a good solution, because we are trying not to use native pointers. We want pointers that are either pointing to a valid object or are null.


--------------------------------------------------------------------------------

Here's a solution: we need weak smart pointers!

They will be just like regular reference counter pointers, only their references won't count. If you have a "strong" pointer and a weak pointer pointing to the same object, and the strong pointer is destroyed, the weak pointer immediately becomes null.


--------------------------------------------------------------------------------

How do we implement this? We keep two reference counts: One for total number of pointers, and one for strong pointers.

When dereferencing a weak pointer, we check the strong reference count. If it is zero, we return NULL.


--------------------------------------------------------------------------------

Try it out! The code is right here: SafePtr.zip.

The code is done using the Intel C++ compiler for the Windows platform.

You need a compiler that can handle templates correctly. Visual C++ (version 6, service pack 4) chokes on them and either silently makes a compilation error or gives an internal compiler error.

If you are not using Windows you will need to modify the SmartPtr.h file. It uses the Windows API function InterlockedIncrement and InterlockedDecrement to modify the reference count. These functions are nothing more than a thread-safe way to increment and decrement a long. Each OS or compiler should have the equivalents, you just have to find them.


--------------------------------------------------------------------------------

There are three files in the archive:

safeptr.h - this is the one that you need to include in order to use the smart pointers; everything is in the namespace named 'safe'.

test.cpp - this is a program that puts the smart pointer through the hoops

demo.cpp - look at this one if you want to learn how to use the library



Read more...


--------------------------------------------------------------------------------

Content of this site is © Dejan Jelovic. All rights reserved.

[ Last edited by 幻影无痕 on 2006-11-29 at 08:00 ]
回复此楼
做人要厚道啊!厚道啊!
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
2楼2005-12-22 18:23:51
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 zsglly 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[基金申请] 投票:  有多少人是今天查系统知道结果的? +17 爱看书的可乐 2026-08-26 19/950 2026-08-30 22:24 by xiangy672
[基金申请] 国社科又开始会评了,不知道这次命运如何 +5 雨打竹帘 2026-08-30 9/450 2026-08-30 22:23 by 余韵清
[基金申请] 能否申诉? +4 echo8914667 2026-08-30 5/250 2026-08-30 21:11 by echo8914667
[基金申请] 为什么到现在没收到通知? +5 tannykie 2026-08-29 5/250 2026-08-30 21:05 by purplejack
[基金申请] 中青基了要发朋友圈吗? +4 349506619 2026-08-28 4/200 2026-08-29 22:41 by alongwaytogo
[基金申请] 国自然面上复盘~欢迎讨论 (金币+15) +15 晴天加油 2026-08-26 16/800 2026-08-29 18:28 by symmetry
[基金申请] 系统查不到 +11 董八千 2026-08-26 11/550 2026-08-28 18:06 by Leogzhya
[基金申请] 基金不中,共勉 +11 eulota 2026-08-26 11/550 2026-08-28 14:22 by 火星超人xi
[基金申请] 哪位高人中了,把查询到的截图贴出来让我看看,让我长长见识 +5 yuleib84 2026-08-26 6/300 2026-08-28 00:02 by yudaoqian88
[基金申请] 面上合作单位盖章 +5 ssyjh 2026-08-27 5/250 2026-08-27 20:50 by gdfollow
[文学芳草园] 梦想 +3 myrtle 2026-08-26 3/150 2026-08-27 10:01 by angelyueyi
[基金申请] 为什么国自然不能直接公布 +4 bjdxyxy 2026-08-26 4/200 2026-08-26 13:12 by qingmu1201
[基金申请] 国际合作可查了,中了面上 (EPI+1)(金币+50) +18 Ldrop2023 2026-08-26 18/900 2026-08-26 11:15 by cmrandy
[基金申请] 项目信息和经费信息在系统里都可以看到了 +6 wittyboy 2026-08-26 14/700 2026-08-26 10:55 by wittyboy
[基金申请] 国合可查了 +3 paperzjh 2026-08-26 3/150 2026-08-26 10:41 by LemmonTr
[基金申请] 今天务委会开完了,明天出结果吗 +19 angus9576 2026-08-25 23/1150 2026-08-26 10:03 by zp519
[基金申请] 国合现在查不到了吗? +10 chengyan1220 2026-08-24 20/1000 2026-08-26 08:57 by peasantsprig
[基金申请] 牛来!米来!面来! +8 beefly 2026-08-26 8/400 2026-08-26 08:37 by xuzhipiao
[基金申请] 在坚冰还盖着北海的时候,我看到了怒放的梅花。 (金币+10) +6 ziyangfang 2026-08-25 9/450 2026-08-25 20:26 by huagongfeihu
[基金申请] 没有任何消息-是不是就凉了 +9 图啦图啦 2026-08-24 10/500 2026-08-25 11:59 by 南海小哥
信息提示
请填处理意见