C++宏以确保释放已用内存?

发布于 2024-11-05 20:59:38 字数 586 浏览 0 评论 0原文

所以我有点不懂行,正在阅读有关 newdelete 和指针的内容,而且我确信在我的一生中我会忘记太多的删除操作。所以我想知道像下面这样的宏是否会比它的价值更麻烦。

#define withObject(ptr, value, BODY)                       \
{                                                           \
     ptr = value;                                           \
     BODY                                                   \
     delete ptr;                                            \ 
     ptr=NULL                                               \
}

这个宏会导致一些问题或者以意想不到的方式运行吗?

编辑:哎呀,我在释放时留下了 d 。好的,谢谢大家的回答。

So I am a bit of a n00b and was reading about new, delete, and pointers, and I am certain that I will forget too many deletes over the course of my life. So I was wondering if a macro like the following would be more trouble than it's worth.

#define withObject(ptr, value, BODY)                       \
{                                                           \
     ptr = value;                                           \
     BODY                                                   \
     delete ptr;                                            \ 
     ptr=NULL                                               \
}

Would this macro cause some problems or behave in an unexpected way?

Edit: oops I left off the d on freed. Well thanks everyone for the answers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

|煩躁 2024-11-12 20:59:38

不,不要这样做。它不会防止内存泄漏或杂散指针。相反,请阅读智能指针。当前的标准提供了一种 auto_ptr 的形式,但还有更多(和更好的)可用,具体取决于您的 C++ 平台。

另外,我怀疑您可能过度使用 new 和 delete - 它们应该在您的代码中很少使用。您应该更喜欢使用值。因此,不要像这样:

string * s = new string ( "foobar" );
....
delete s;

您应该简单地编写:

string s( "foobar" );

并让编译器为您管理字符串的生命周期。

No, do not do this. It won't prevent either memory leaks or stray pointers. Instead, read up on smart pointers. The current standard provides one in the shape of auto_ptr, but many more (and better ones) are available, depending on your C++ platform.

Also, I suspect you may be over-using new and delete - they should be used very rarely in your code. You should prefer to use values. So instead of something like this:

string * s = new string ( "foobar" );
....
delete s;

you should simply write:

string s( "foobar" );

and have the compiler manage the lifetime of the string for you.

苍景流年 2024-11-12 20:59:38

无需在这里重新发明轮子,您正在寻找智能指针

非常有用的 Boost 库有 智能指针功能。

No need to reinvent the wheel here, you are looking for smart pointers.

The very useful Boost library has smart pointer functionality.

打小就很酷 2024-11-12 20:59:38

google RAII 习惯用法;它是一样的,但不那么老套;然后,您可以使用无处不在的智能指针(当它们超出使用/范围时自动释放内存)将其应用于动态分配。

Boost 包含最著名/最广泛的智能指针版本(几种风格)。

C++ 标准一直有一种有缺陷的智能指针,名为 auto_ptr。这是一个有警告的地方,但它本身很有用(RTFM!)。

C++0x 采用了几个 Boost TR1 类,包括最流行的智能指针(我希望我的措辞正确,因为标准语言通常在细节上非常具体)

HTH

google RAII idiom; it is the same but not so hacky; you can then apply this on your dynamic allocations using the ubiquitous smartpointers (which automatically free memory when they go out of use/scope).

Boost contains the most famous/widespread version of a smart pointers (seveal flavours).

The C++ standard has always had a kind of crippled smart pointer, named auto_ptr. This is one with caveats but useful in it's own right (RTFM!).

C++0x adopts several of the Boost TR1 classes, including the most popular smart pointer (I hope I'm wording this right because the standardese is usually quite specific on details)

HTH

梦与时光遇 2024-11-12 20:59:38

您正在寻找智能指针模式。它是标准 C++,在此站点中有详细解释。

You're looking for the smart pointer pattern. It's standard C++ and explained in detail at this site.

﹎☆浅夏丿初晴 2024-11-12 20:59:38

除了您确实应该使用智能指针(即使是低级的 auto_ptr 也能满足您的目的)这一事实之外,BODY 还可能存在问题。使用可能很大的代码段作为类似函数的宏的参数有其自身的陷阱。例如,如果 BODY 中存在未加括号的逗号,则 BODY 会变成两个参数。我不确定进一步的问题,因为我从未见过有人尝试过。

不要在 C++ 中使用类似函数的宏。这很少值得。

Aside from the fact that you really should use smart pointers (even the lowly auto_ptr will serve for your purpose), there's possible problems with BODY. Using a potentially large section of code as an argument for a function-like macro has its own traps. For example, if there's an unparenthesized comma in BODY, then BODY turns to two arguments. I'm not sure of further issues, because I've never seen anybody try it.

Don't use function-like macros in C++. It's rarely worth it.

酒浓于脸红 2024-11-12 20:59:38

看起来您希望分配一个对象,对其进行一小部分工作,然后删除它。为此,我建议使用 std::auto_ptr。

It looks like you wish to allocate an object, do a short piece of work on it, then delete it. For this purpose I would suggest std::auto_ptr.

天赋异禀 2024-11-12 20:59:38

执行此类操作的惯用 C++ 方法不是使用宏,而是使用使用 资源的“智能指针”类获取就是初始化。例如,Boost 的 scoped_ptr 在上下文中可以很好地工作你的宏在哪里有意义。

我将在这里放置一个智能指针类的草图 - 但我省略了很多细节。这只是为了让您了解它们是如何工作的。使用scoped_ptr代替,他们没有遗漏任何东西。

template <typename T>
class smartptr<T> {
public:
    smartptr() : ptr(new T) {}
    smartptr(T* p) : ptr(p) {}
    ~smartptr() { delete ptr }
    T& operator*() { return *ptr; }
    T* operator->() { return ptr; }
private:
    T* ptr;
}

The idiomatic C++ way to do this sort of thing is not with macros, but with "smart pointer" classes that use Resource Acquisition is Initialization. For instance, Boost's scoped_ptr would work nicely in the contexts where your macro would make sense.

I'll put a sketch of a smart pointer class here - but I'm leaving out a lot of details. This is just to give you an idea of how they work. Use scoped_ptr instead, they didn't leave anything out.

template <typename T>
class smartptr<T> {
public:
    smartptr() : ptr(new T) {}
    smartptr(T* p) : ptr(p) {}
    ~smartptr() { delete ptr }
    T& operator*() { return *ptr; }
    T* operator->() { return ptr; }
private:
    T* ptr;
}
冷月断魂刀 2024-11-12 20:59:38

这个宏会导致一些问题或者以意想不到的方式运行吗?

如果 BODY 抛出异常,那么删除将被跳过。

解决方案是使用“RAII”习惯用法。它是现代 C++ 编程中最重要的概念之一。

Would this macro cause some problems or behave in an unexpected way?

If BODY throws an exception then the delete will be skipped.

The solution is to make use of the "RAII" idiom. It's one of the most important concepts in modern C++ programming.

愿与i 2024-11-12 20:59:38

我认为更好的解决方案是创建一个分配和删除宏而不是一个包罗万象的宏。这是一件非常混乱、没有多大帮助的事情

当我在 CI 中编程时,通常会执行如下操作:

#define ALLOC_ARY(type, sz) (type*)calloc(sz, sizeof(type))
#define ALLOC_STR(sz) ALLOC_ARY(char, sz)

char *string = ALLOC_STR(128);
int *array = ALLOC_ARY(int, 20);

但记住在 vanilla C 中释放只是其中的一部分:

free(string); string = NULL;
free(array); array = NULL;

编辑:对于 C++,智能指针正如其他人所建议的那样,这是一个好方法。

I think a better solution would make an allocate and delete macro instead of an all-inclusive. Thats a really messy, not very helpful thing to do

When I program in C I commonly do something like the following:

#define ALLOC_ARY(type, sz) (type*)calloc(sz, sizeof(type))
#define ALLOC_STR(sz) ALLOC_ARY(char, sz)

char *string = ALLOC_STR(128);
int *array = ALLOC_ARY(int, 20);

But remembering to free in vanilla C is just part of it:

free(string); string = NULL;
free(array); array = NULL;

Edit: For C++, smart pointers as others have suggested are a good way to go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文