Really? let's have a look at a piece of code then.
Code:
void SomeFunc(void)
{
int *x = new int[100];
SomeOtherFunc(x);
delete[] x;
}
we've allocated some memory, called a function, deleted our memory like a responsible programmer and all is happy in the valleys, right?
but let's have a look at SomeOtherFunc()
Code:
struct big
{
double d[100000];
}
void SomeOtherFunc(int *p)
{
for (int i = 0; i < 200; i++)
{
p[i] = i;
}
big *reallyBig = new big[100000];
// some code
delete[] big;
}
ok this code has 2 problem (apart from not doing anything useful). The first is that we've overwritten the bounds of our array. Not such a big deal, we should've passed in the size of the array, but it wouldn't necessary with a vector (which knows it's size).
The second is a bit trickier. You see, there's a very good chance that we don't have enough memory to allocate reallyBig. On a standards-compliant compiler, that means an std::bad_alloc exception will be thrown. Now we're in really big trouble since x will not be deleted.
ok, but we can catch the exception! so let's rewrite SomeFunc
Code:
void SomeFunc(void)
{
int *x;
try
{
x = new int[100];
SomeOtherFunc(x);
delete[] x;
}
catch (std::bad_alloc &)
{
delete[] x;
}
}
ahh, much better. except, we've swallowed the exception so the caller of SomeFunc doesn't know it failed. No problem, let's rethrow the exception.
Code:
void SomeFunc(void)
{
int *x;
try
{
x = new int[100];
SomeOtherFunc(x);
delete[] x;
}
catch (std::bad_alloc &)
{
delete[] x;
throw;
}
}
phew! dodged that bullet. except now another coder has changed SomeOtherFunc()!
Code:
struct big
{
double d[100000];
}
void SomeOtherFunc(int *p)
{
for (int i = 0; i < 200; i++)
{
p[i] = i;
}
big *reallyBig = new big[100000];
if (!ConnectToInternet())
{
throw Unconnected();
}
delete[] big;
}
ahh crap, now we have to add
another catch clause. That sucks. To hell with that, let's just catch all exceptions.
Code:
void SomeFunc(void)
{
int *x;
try
{
x = new int[100];
SomeOtherFunc(x);
delete[] x;
}
catch (...)
{
delete[] x;
throw;
}
}
or instead we could just write
Code:
void SomeFunc(void)
{
std::vector<int> x(100);
SomeOtherFunc(x);
}
struct big
{
double d[100000];
}
void SomeOtherFunc(std::vector<int> & p)
{
for (int i = 0; i < p.size(); i++)
{
p[i] = i;
}
std::vector<big> reallyBig(100000);
if (!ConnectToInternet())
{
throw Unconnected();
}
}
I know which one is safer. I know which one is cleaner. I know which one is more extensible and I know which I'd prefer.
Feel free to keep using dynamic arrays.
and while I'm at it...
That statement is completely backwards. I don't like relying on my own code. I much prefer to use some existing code that's been tested and documented.
did it take you long to write your own os? your own compiler? browser? ok maybe that's pushing it, but have you written your own versions of cout/printf? ever written a gui library?