|
|
Am 21.11.2013 20:57, schrieb Orchid Win7 v1:
> Today, something blew my mind.
>
> I was surfing the net, and I happened to wonder about how best ensure
> stuff gets freed while coding in C++. So I went to Stack Overflow. There
> was an accepted answer about RAII - but right below it, with 5x the
> up-votes, was an answer that basically said
>
> Everybody says RAII, and that's a good answer. But there's a better
> one: DON'T allocate dynamic memory in the first place! That is, rather
> than writing
>
> Foo * foo = new Foo();
>
> just write
>
> Foo foo();
>
> Reflecting on this for a moment, I saw the wisdom of it. If your stuff
> isn't dynamic, you can never ever forget to free it, leave it dangling,
> or have any of the other problems associated with manual memory
> allocation. (About the worst thing you can do is give somebody else a
> pointer to it - don't do that!)
>
> But then I wondered... how can I apply that here?
>
> char * buffer = new char[1024];
> stream.read(buffer, 1024);
> ...stuff...
> delete[] buffer;
>
> The thing that actually confused me was what the syntax for creating a
> non-dynamic array is - I've never seen anybody do that before. Ever.
> (Not in C or C++, anyway.) It turns out the answer is pretty trivial:
>
> char buffer[1024];
> stream.read(buffer, 1024);
>
> Now you don't have to *care* that the function might have fifteen return
> statements, or that stuff might throw exceptions... your memory will
> *always* be deallocated when you leave. Because that's how stacks work.
>
> But then somebody else pointed out that this is find for a 1KB buffer,
> but probably a bad idea for a 10MB one. (It also fails if you don't
> statically know how much data you want - which is pretty much the
> *original* reason for inventing dynamic allocation in the first place...)
>
> The suggested solution? "Why don't you just use a std::vector<char>?"
Now /that/ is smart... avoiding allocation of dynamic memory by a class
that /encapsulates/ dynamic memory allocation...
Anyone notice that this /is/ the RAII principle?!
So if we're using RAII anyway, what's wrong with
{
auto_ptr<char*> buffer = auto_ptr<char*>(new char[N]);
stream.read(*buffer, N);
//...stuff...
//...oops, forgot to de-allocate... or did I?
}
(except that you need to use either the tr1 library or boost)?
> I'm still trying to figure out whether this audacious assumption about
> the internal behaviour of a library class is more or less evil than just
> trying to do manual memory management correctly...
>
> Manual memory management? Pretty evil.
>
> Relying on internal library implementation details? Pretty evil.
Automatic memory management using smart pointers? Pretty smart.
Post a reply to this message
|
|