By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,919 Members | 1,074 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,919 IT Pros & Developers. It's quick & easy.

memory leak in the code?

P: n/a
Hello everyone,
Should I delete memory pointed by pointer a if there is bad_alloc when
allocating memory in memory pointed by pointer b? I am not sure
whether there will be memory leak if I do not delete a.

Expand|Select|Wrap|Line Numbers
  1. try {
  2. a = new int [N];
  3. b = new int [M];
  4. } catch (bad_alloc)
  5. {
  6. // if a success, but b fail, should we try to delete[] a here to
  7. avoid memory leak?
  8.  
  9. }
  10.  

thanks in advance,
George
Jan 5 '08 #1
Share this Question
Share on Google+
27 Replies


P: n/a
On 2008-01-05 16:04, George2 wrote:
Hello everyone,
Should I delete memory pointed by pointer a if there is bad_alloc when
allocating memory in memory pointed by pointer b? I am not sure
whether there will be memory leak if I do not delete a.

Expand|Select|Wrap|Line Numbers
  1. try {
  2.     a = new int [N];
  3.     b = new int [M];
  4. } catch (bad_alloc)
  5. {
  6.     // if a success, but b fail, should we try to delete[] a here to
  7. avoid memory leak?
  8. }
  9.  
Yes, but what about if you get a bad_alloc when allocating a? Then you
will try to delete whatever memory that the garbage in a points to. To
prevent this use something like this instead:

try {
int* a = 0;
a = new int[N];
int* b = new int[N];
}
catch (bad_alloc)
{
delete[] a;
}

Or use some kind of smart pointer, in which case you do not need to try-
block since the pointers will free any memory if the exception is thrown.

auto_ptr<inta = new int[N];
auto_ptr<intb = new int[N];

Note also that depending on what type of application you are writing it
might be useless to catch bad_alloc (except for diagnostic purposes)
since it can be quite hard to recover from. In all applications I have
written a bad_alloc is a terminal failure.

--
Erik Wikström
Jan 5 '08 #2

P: n/a
"Erik Wikström" <Er***********@telia.comwrote in message
news:zP*****************@newsb.telia.net...
Yes, but what about if you get a bad_alloc when allocating a? Then you
will try to delete whatever memory that the garbage in a points to. To
prevent this use something like this instead:

try {
int* a = 0;
a = new int[N];
int* b = new int[N];
}
catch (bad_alloc)
{
delete[] a;
}
Well, the idea is right but the implementation is wrong, because a will be
out of scope in the delete statement. Moreover, unless a and b are deleted
inside the try, the code will leak memory if it succeeds, because once a and
b are out of scope, there's no further opportunity to delete the memory.

An alternative:

int* a = 0;
try {
a = new int[N];
int* b = new int[N];

// do additional work here

delete[] b;
delete[] a;
} catch (bad_alloc) {
delete[] a;
}

I agree with you that smart pointers are the way to go here :-)
Jan 5 '08 #3

P: n/a
On Jan 5, 10:04 am, George2 <george4acade...@yahoo.comwrote:
Hello everyone,

Should I delete memory pointed by pointer a if there is bad_alloc when
allocating memory in memory pointed by pointer b? I am not sure
whether there will be memory leak if I do not delete a.

[code]
try {
a = new int [N];
b = new int [M];} catch (bad_alloc)

{
// if a success, but b fail, should we try to delete[] a here to
avoid memory leak?
I have doubts, so lets find out, Mr Holmes:

#include <iostream>
#include <stdexcept>

class A
{
static int count;
public:
A()
{
std::cout << "A()\n";
if(2 == count)
throw std::bad_alloc();
count++;
}
~A() { std::cout << "~A()\n"; }
};

int A::count;

class B
{
public:
B() { std::cout << "B()\n"; }
~B() { std::cout << "~B()\n"; }
};

int main()
{
A* p_a = 0;
B* p_b = 0;
try {
p_b = new B[5];
p_a = new A[5];
} catch (const std::bad_alloc& e)
{
std::cout << "error: ";
std::cout << e.what() << std::endl;
}
}

/*
B()
B()
B()
B()
B() // obviously, something is wrong
A()
A()
A()
~A()
~A()
error: St9bad_alloc
*/

So we definitely have a problem.
Is the solution to delete [] p_a?
no. thats the wrong solution, there is a simpler, better way.
A std::vector own its elements unless these are pointers.
also, a std::vector invokes copy construction to populate elements at
creation time.
So to track what is happening, we need to modify A's copy ctor to
increment a static counter.

....
#include <vector>

class A
{
static int copy_count;
static int count;
public:
...
// A's copy ctor
A::A( const A& copy)
{
std::cout << "copy A\n";
if(2 == copy_count)
throw std::bad_alloc();
copy_count++;
}
...
};

int A::count;
int A::copy_count;

int main()
{
try
{
std::vector< B vb(5);
std::vector< A va(5);
}
catch (const std::bad_alloc& e)
{
std::cout << "error: ";
std::cout << e.what() << std::endl;
}
}

/*
B()
~B() // the entire vector vb is initialized with a copy
A() // default ctor
copy A // copy_count = 0
copy A
copy A // copy_count = 2, kaboom!
~A()
~A()
~A()
~B() // automatic
~B()
~B()
~B()
~B()
error: St9bad_alloc
*/

moral: When you aren't sure, test it.
And prove the solution.
Don't use pointers, you could use a boost::scoped_array.
Jan 5 '08 #4

P: n/a
On Jan 5, 3:04*pm, George2 <george4acade...@yahoo.comwrote:
Hello everyone,

Should I delete memory pointed by pointer a if there is bad_alloc when
allocating memory in memory pointed by pointer b? I am not sure
whether there will be memory leak if I do not delete a.

Expand|Select|Wrap|Line Numbers
  1. try {
  2. * * a = new int [N];
  3. * * b = new int [M];} catch (bad_alloc)
  4. {
  5. * * // if a success, but b fail, should we try to delete[] a here to
  6. avoid memory leak?
  7. }
  8.  

Interesting problem...

In theory in the above case you could do something like the following:
int * a = 0;
int * b = 0;
try {
a = new int [N];
try{
b = new int[M];
}
catch {bad_alloc){
delete a;
/* b didnt get allocated */
return;
}
/* delete a,b */
return;
}
catch bad_alloc{
/* neither a or b got allocated */
return;
}

However if looked at from a practical viewpoint, In case of
bad_alloc the most likely cause is that the system has run out of
memory.

Firstly It is a reasonable idea to try to detect bad_alloc
exceptions.

The problem then is once detected, what to do about them?

Its certainly useful ( IMO essential , at least polite) to try to
report this to the user, for which you need to catch the exception,
But bear in mind that you are equivalent to the drowning man in the
flooded room gulping the last bit of air, IOW you don't want to even
attempt any more heap allocations if at all possible, but pretty much
anything you do to output a diagnostic to the user may request
allocations. Neveretheless in this sitaution things can't get much
worse, so you should probably try doing the diagnostic (by calling
some code designed for this particular situation) and quit the
application if thats acceptable.

The point of this is...

If that's the strategy, you adopt then any dangling pointers will be
cleaned up by the system so its not worth worrying about them in
practise. Its also simple. You have done the right thing by the user.
Its their problem now.
If that strategy is unacceptable and you hope to continue the app,
then you are into a much more complicated ballgame. You have to find
some way to have some scratch space so you can then set about trying
the complicated task of regaining a useful amount of heap, and you
will need to deal with raw pointers owning heap real estate such as
'a'.

Another answer is. Dont use new, at least not in functions. If at all
possible allocate in class constructors and release in destructors.
(RAII) Then you will find that the problem is dealt with
automatically, because the destructor for the class allocated on the
stack is called automatically when an exception is thrown. This is how
most std::library types work under the hood (std::string , containers
etc

Smart pointers are another option rather than raw pointers.

regards
Andy Little


Jan 5 '08 #5

P: n/a
George2 <ge*************@yahoo.comwrote:
Should I delete memory pointed by pointer a if there is bad_alloc when
allocating memory in memory pointed by pointer b? I am not sure
whether there will be memory leak if I do not delete a.

Expand|Select|Wrap|Line Numbers
  1. try {
  2.     a = new int [N];
  3.     b = new int [M];
  4. } catch (bad_alloc)
  5. {
  6.     // if a success, but b fail, should we try to delete[] a here to
  7. avoid memory leak?
  8. }
  9.  
The proper way to do the code above is:

a = 0;
b = 0;
try {
a = new int [N];
b = new int [N];
}
catch( bad_alloc ) {
delete [] a;
delete [] b;
}

But the best way is to turn 'a' and 'b' into vector<int>s.
Jan 5 '08 #6

P: n/a
On Jan 5, 5:21 pm, "Andrew Koenig" <a...@acm.orgwrote:
"Erik Wikström" <Erik-wikst...@telia.comwrote in message
news:zP*****************@newsb.telia.net...
Yes, but what about if you get a bad_alloc when allocating a? Then you
will try to delete whatever memory that the garbage in a points to. To
prevent this use something like this instead:
try {
int* a = 0;
a = new int[N];
int* b = new int[N];
}
catch (bad_alloc)
{
delete[] a;
}
Well, the idea is right but the implementation is wrong,
because a will be out of scope in the delete statement.
Moreover, unless a and b are deleted inside the try, the code
will leak memory if it succeeds, because once a and b are out
of scope, there's no further opportunity to delete the memory.
An alternative:
int* a = 0;
try {
a = new int[N];
int* b = new int[N];
// do additional work here
delete[] b;
delete[] a;
} catch (bad_alloc) {
delete[] a;
}
I agree with you that smart pointers are the way to go here :-)
But not std::auto_ptr, since it does delete ptr, and not
delete[] ptr.

I actually disagree about using smart pointers here.
std::vector seems far more appropriate.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jan 5 '08 #7

P: n/a
On Jan 5, 5:38 pm, kwikius <a...@servocomm.freeserve.co.ukwrote:
On Jan 5, 3:04 pm, George2 <george4acade...@yahoo.comwrote:
However if looked at from a practical viewpoint. In case of
bad_alloc the most likely cause is that the system has run out
of memory.
As a result of 1) your application using too much memory in
handling a specific request---in which case, you can return an
error (e.g. insufficient resources) for the request, and still
continue to operate, or 2) your application leaks memory---in
which case, you really do need to get out of there, as quickly
as possible, because the situation isn't going to get any better
anytime soon.
Firstly It is a reasonable idea to try to detect bad_alloc
exceptions.
The problem then is once detected, what to do about them?
In the first case, above, you respond with an error to the
request, saying that you can't handle it.

Whether such cases are plausible or not depends a lot on the
application. I've worked on servers in which "requests" had a
more or less open structure (e.g. represented an arbitrary
expression, usually in some variant of RPN)---LDAP comes to
mind. In such cases, you don't want to abort the server just
because some client goes overboard with his search criteria in
one particular request. (But I'll admit that the case is pretty
special, and probably doesn't apply to most applications. Also,
if you find yourself in such a case, you'll have to work out
something to avoid stack overflow as well.)
Its certainly useful (IMO essential, at least polite) to try
to report this to the user, for which you need to catch the
exception,
Interesting. I've always replaced the new_handler.

If you replace the new_handler, then operator new will
effectively become a nothrow (provided the constructor of the
object cannot throw for other reasons). This can be useful in
certain situations.

Of course, if you replace the new_handler, then such an error
won't cause the destructors on the stack to be called. Which
may be a problem as well. I tend to organize things so that it
won't be a problem, as much as possible, because there are other
cases where they won't be called either (e.g. if you core dump).
Such cases are all probably errors, but then, if you get a
bad_alloc because the program leaks memory, that's a programming
error as well.

(I'm not saying that the points you're raising aren't valid.
Only that there are a lot of things that have to be considered,
depending on the actual application.)
But bear in mind that you are equivalent to the drowning man
in the flooded room gulping the last bit of air, IOW you don't
want to even attempt any more heap allocations if at all
possible, but pretty much anything you do to output a
diagnostic to the user may request allocations.
Referring to my two situations in the first paragraph I wrote:
In case 1, the stack walk back due to the exception will free up
all of the memory the request allocated, so by the time you
catch the exception, there should be no real problem. In case
2: I've always pre-allocated any memory that might be needed to
output such critical error messages before starting operation,
just to be sure that it was there if the case occured.
Neveretheless in this sitaution things can't get much worse,
so you should probably try doing the diagnostic (by calling
some code designed for this particular situation) and quit the
application if thats acceptable.
The point of this is...
If that's the strategy, you adopt then any dangling pointers
will be cleaned up by the system so its not worth worrying
about them in practise. Its also simple. You have done the
right thing by the user. Its their problem now.
You have very tolerant users. If my server goes down, even if
the reason is due to bad_alloc, my users complain to me. (In a
number of cases, there have even been conventional penalties for
down time.)
If that strategy is unacceptable and you hope to continue the app,
then you are into a much more complicated ballgame. You have to find
some way to have some scratch space so you can then set about trying
the complicated task of regaining a useful amount of heap, and you
will need to deal with raw pointers owning heap real estate such as
'a'.
You have to know why you ran out of memory. If the only
possible reason for running out of memory is a memory leak in
your code (a frequent case in the context I work, where the
server, once written, runs on a dedicated machine with no other
applications on it), then of course, continuing is out of the
question. If the reason is that you've received a request that
required too many resources, the problem is handled
automatically by aborting the request.
Another answer is. Dont use new, at least not in functions. If
at all possible allocate in class constructors and release in
destructors. (RAII) Then you will find that the problem is
dealt with automatically, because the destructor for the class
allocated on the stack is called automatically when an
exception is thrown. This is how most std::library types work
under the hood (std::string , containers etc
Smart pointers are another option rather than raw pointers.
If it's only memory you're worried about, garbage collection is
the easiest solution. The same issues arise for other
resources, however, or even just issues of system coherence
(transactional integrity).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 5 '08 #8

P: n/a
On Jan 5, 6:47 pm, "Daniel T." <danie...@earthlink.netwrote:
George2 <george4acade...@yahoo.comwrote:
Should I delete memory pointed by pointer a if there is
bad_alloc when allocating memory in memory pointed by
pointer b? I am not sure whether there will be memory leak
if I do not delete a.
Expand|Select|Wrap|Line Numbers
  1.  try {
  2.      a = new int [N];
  3.      b = new int [M];
  4.  } catch (bad_alloc)
  5.  {
  6.      // if a success, but b fail, should we try to delete[] a here to
  7.  avoid memory leak?
Expand|Select|Wrap|Line Numbers
  1.  
  2.         
  3.                         
  4.                  }
  5.  
  6.  
The proper way to do the code above is:
a = 0;
b = 0;
try {
a = new int [N];
b = new int [N];}
catch( bad_alloc ) {
delete [] a;
delete [] b;
}
But the best way is to turn 'a' and 'b' into vector<int>s.
Since when is the "best way" not the "proper way"? Your
solution is "correct", of course, as would be using
boost::scoped_array. But as you say, the best way is to use
std::vector< int >. Anything else is less good.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 5 '08 #9

P: n/a
On Jan 5, 6:53*pm, James Kanze <james.ka...@gmail.comwrote:
On Jan 5, 5:38 pm, kwikius <a...@servocomm.freeserve.co.ukwrote:
Neveretheless in this sitaution things can't get much worse,
so you should probably try doing the diagnostic (by calling
some code designed for this particular situation) and quit the
application if thats acceptable.
The point of this is...
If that's the strategy, you adopt then any dangling pointers
will be cleaned up by the system so its not worth worrying
about them in practise. Its also simple. You have done the
right thing by the user. *Its their problem now.

You have very tolerant users. *If my server goes down, even if
the reason is due to bad_alloc, my users complain to me. *(In a
number of cases, there have even been conventional penalties for
down time.)
Its an interesting problem, and the solution is very dependent on the
context, the platform, the type of application and so on, as you say.

Its also quite tricky to diagnose who is to blame. It could be other
applications on the system, it could be that the size of some
structure is dependent on parameters supplied by the user, or it could
(dare I say it) even be the fault of the application.

The bare minimum is to try to get some feedback to the user about the
problem (ideally too to provide a probable cause and even if possible
a suggested solution), after all if users are complaining then you
have users. Its when they arent complaining that you need to worry...
either your system is perfect, or you have no users ;-)

After satisfying that criteria, then I agree that doing anything more
useful is complicated. For example the user may have asked for you to
create a huge structure, but you may have a memory leak anyway. In
this case backing off and (recursively) telling the user that their
last request was too big will be very frustrating!

That is a case I have encountered as a user, and its a very good
argument for not allocating raw pointers :-)

I guess you also need to weigh up how much time you spend on error
feedback, versus the time you spend on adding cool new features.

Of course the app may be a compiler. For example one of the goals of
CLANG is provide better diagnostics. Ultimately, trying to provide
useful error feedback does come to dominate everything in many
applications ( The timeline for a useful C++ frontend is a couple of
years)

http://clang.llvm.org/

regards
Andy Little


Jan 6 '08 #10

P: n/a
Erik Wikström wrote:
Or use some kind of smart pointer, in which case
you do not need to try-block since the pointers
will free any memory if the exception is thrown.

* auto_ptr<inta = new int[N];
* auto_ptr<intb = new int[N];
I agree. It is better to use any kind (standard or self-maded) of
wrapper to control ownership of memory or other shared resources. C++
hard desined for technic known as RAII (read http://www.hackcraft.net/raii/
).
Jan 6 '08 #11

P: n/a
kwikius wrote:
>
int * a = 0;
int * b = 0;
try {
* * a = new int [N];
...
* * * delete a;
Excellent :). As i know, for each program we get at least one (hard to
detect and with random runtime apperance) error due to improper delete/
delete[] usage.

For example, the stupid program ( http://grizlyk1.narod.ru/cpp_new/gcc/utils
) for adding source lines into gcc asm output has 3 levels of patching
of detected errors. Take a look at the last patch, file "to_do.txt":

1. possible memory leakage.

void Terr::do_copy(const char *const who)
{
if(who)try
{
const uint len=strlen(who);
if(!len)return;

char *const tmp=new char[len+1];
strcpy(tmp,who);
msg_copied=tmp;
}
catch(...){ msg_shared="no memory"; }
}

"strcpy(tmp,who)" can throw while "tmp" has no owner

patch:
char *const tmp=new char[len+1];
try{ strcpy(tmp,who); }catch(...){ delete[] tmp; throw; }
msg_copied=tmp;

2. Wrong delete for arrray

~Terr::Terr(){ delete msg_copied; }

patch:
~Terr::Terr(){ delete[] msg_copied; }

3. Wrong delete for arrray

Terr& operator= (const Terr& obj)
{
if( &obj != this )
{
msg_shared=obj.msg_shared;
delete msg_copied; msg_copied=0;
do_copy(obj.msg_copied);
}
return *this;
}

patch:
if(msg_copied){delete[] msg_copied; msg_copied=0;}

I agree, that the errors appeared due to my negligent work, this is
very bad habbit for programming, but there are many other people with
the same behaviour in the world. This is constant fact of nature :).

And in addition, any desing work, being continuous iterational
process, inspires a little the negligence in work ( :) I have found
the couse ).

So, the only way to prevent the errors is explicit memory
declarations:

char * ptr; //C-style pointer
auto char * ptr; //can not delete/delete[]
heap char * ptr; //can delete heap/delete
heap[] char * msg_copied; //can delete heap[]/delete[]
other_memory_type char *ptr; //can delete other_memory_type

Maybe it will be added to C++.

Maksim A. Polyanin
old page about some C++ improvements:
http://grizlyk1.narod.ru/cpp_new
Jan 6 '08 #12

P: n/a
On 2008-01-06 09:55:10 -0500, Grizlyk <gr******@yandex.rusaid:
Erik Wikström wrote:
>Or use some kind of smart pointer, in which case
you do not need to try-block since the pointers
will free any memory if the exception is thrown.

* auto_ptr<inta = new int[N];
* auto_ptr<intb = new int[N];

I agree. It is better to use any kind (standard or self-maded) of
wrapper to control ownership of memory or other shared resources.
Well, not "any kind". Just an appropriate kind, which, in this example,
auto_ptr is not. It uses scalar delete, not vector delete, so the
behavior when it stores a pointer to a new'ed array is undefined.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Jan 6 '08 #13

P: n/a
On 6 Jan., 19:45, Grizlyk <grizl...@yandex.ruwrote:
kwikius wrote:
int * a = 0;
int * b = 0;
try {
* * a = new int [N];
...
* * * delete a;

Excellent :). As i know, for each program we get at least one (hard to
detect and with random runtime apperance) error due to improper delete/
delete[] usage.
Not in idiomatic C++ where you "never" use operator delete [].
For example, the stupid program (http://grizlyk1.narod.ru/cpp_new/gcc/utils
) for adding source lines into gcc asm output has 3 levels of patching
of detected errors. Take a look at the last patch, file "to_do.txt":
It is quite stupid from a C++ viewpoint as it looks more like C. In
this case, You should expect using C, not C++ style.
>
1. possible memory leakage.

* * void *Terr::do_copy(const char *const who)
* * *{
* * * if(who)try
* * * *{
* * * * const uint len=strlen(who);
* * * * if(!len)return;

* * * * char *const tmp=new char[len+1];
* * * * strcpy(tmp,who);
* * * * msg_copied=tmp;
* * * *}
* * * catch(...){ msg_shared="no memory"; }
* * *}

"strcpy(tmp,who)" can throw while "tmp" has no owner
This is not possible so far as I know. strcpy is C and thus does not
throw. Did you write your own strcpy?
>
patch:
* * * * char *const tmp=new char[len+1];
* * * * try{ strcpy(tmp,who); }catch(...){ delete[] tmp; throw; }
* * * * msg_copied=tmp;

2. Wrong delete for arrray

* * ~Terr::Terr(){ delete msg_copied; }

patch:
* * ~Terr::Terr(){ delete[] msg_copied; }

3. Wrong delete for arrray

* * Terr& operator= (const Terr& obj)
* * *{
* * * if( &obj != this )
* * * *{
* * * * msg_shared=obj.msg_shared;
* * * * delete msg_copied; msg_copied=0;
* * * * do_copy(obj.msg_copied);
* * * *}
* * * return *this;
* * *}

patch:
* * * * if(msg_copied){delete[] msg_copied; msg_copied=0;}

I agree, that the errors appeared due to my negligent work, this is
very bad habbit for programming, but there are many other people with
the same behaviour in the world. This is constant fact of nature :).
Well... you can't fight bad programming in any language.
>
And in addition, any desing work, being continuous iterational
process, inspires a little the negligence in work ( :) I have found
the couse ).

So, the only way to prevent the errors is explicit memory
declarations:

char * ptr; * * * * * * * * *//C-style pointer
auto char * ptr; * * * * * * //can not delete/delete[]
heap char * ptr; * * * * * * //can delete heap/delete
heap[] char * msg_copied; * *//can delete heap[]/delete[]
other_memory_type char *ptr; //can delete other_memory_type

Maybe it will be added to C++.
Why? We already have std::vector (and std::string). Using either of
these would have avoided your problems.
>
/Peter
Jan 6 '08 #14

P: n/a
=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <Er***********@telia.comwrote in
news:zP*****************@newsb.telia.net:
On 2008-01-05 16:04, George2 wrote:
>Hello everyone,
Should I delete memory pointed by pointer a if there is bad_alloc
when
>allocating memory in memory pointed by pointer b? I am not sure
whether there will be memory leak if I do not delete a.

Expand|Select|Wrap|Line Numbers
  1. try {
  2.     a = new int [N];
  3.     b = new int [M];
  4. } catch (bad_alloc)
  5. {
  6.     // if a success, but b fail, should we try to delete[] a here to
  7. avoid memory leak?
  8. }

Yes, but what about if you get a bad_alloc when allocating a? Then you
will try to delete whatever memory that the garbage in a points to. To
prevent this use something like this instead:

try {
int* a = 0;
a = new int[N];
int* b = new int[N];
}
catch (bad_alloc)
{
delete[] a;
}
Bad advice: a isn't in scope in the catch clause.
>
Or use some kind of smart pointer, in which case you do not need to
try-
block since the pointers will free any memory if the exception is
thrown.
>
auto_ptr<inta = new int[N];
auto_ptr<intb = new int[N];
Worse advice. You may not store pointers returned by new[] into an
auto_ptr!
Jan 6 '08 #15

P: n/a
On 6 Jan, 18:45, Grizlyk <grizl...@yandex.ruwrote:
kwikius wrote:
int * a = 0;
int * b = 0;
try {
* * a = new int [N];
...
* * * delete a;

Excellent :). As i know, for each program we get at least one (hard to
detect and with random runtime apperance) error due to improper delete/
delete[] usage.
You got me!

I did spot it some time after I posted, and in a later post started
talking about memory leaks...

What can I say except I don't use raw pointers to heap if at possible.
The above is just one more ouch!.

regards
Andy Little

Jan 7 '08 #16

P: n/a
On Jan 6, 9:19 am, kwikius <a...@servocomm.freeserve.co.ukwrote:
On Jan 5, 6:53 pm, James Kanze <james.ka...@gmail.comwrote:
On Jan 5, 5:38 pm, kwikius <a...@servocomm.freeserve.co.ukwrote:
Neveretheless in this sitaution things can't get much
worse, so you should probably try doing the diagnostic (by
calling some code designed for this particular situation)
and quit the application if thats acceptable. The point
of this is... If that's the strategy, you adopt then any
dangling pointers will be cleaned up by the system so its
not worth worrying about them in practise. Its also
simple. You have done the right thing by the user. Its
their problem now.
You have very tolerant users. If my server goes down, even if
the reason is due to bad_alloc, my users complain to me. (In a
number of cases, there have even been conventional penalties for
down time.)
Its an interesting problem, and the solution is very dependent
on the context, the platform, the type of application and so
on, as you say.
Its also quite tricky to diagnose who is to blame.
By definition, I am to blame. (Or rather, my client, who is
providing the turn key system.)
It could be other applications on the system,
It's a dedicated system. There aren't (or shouldn't be) any
other "applications". Of course, there could be a bug in some
system service, that caused it to leak memory. But since we
decided to use Sun Solaris, running on a Sparc, rather than some
other system, that's our fault too. The contract is clear:
10.000 Euro per minute for down time. (I presume that there are
exceptions if, e.g. someone carelessly unplugs the machine, or
it gets destroyed in a terrorist attack, or something like
that.)
it could be that the size of some structure is dependent on
parameters supplied by the user,
We verify the parameters supplied by the user (the
configuration) before accepting it.
or it could (dare I say it) even be the fault of the
application.
As I said, the assumption is that if the application gets
bad_alloc, it is leaking memory.
The bare minimum is to try to get some feedback to the user
about the problem (ideally too to provide a probable cause and
even if possible a suggested solution),
We have logs, we can change the log configuration without
stopping the process, and we can even ftp into the users machine
to recover the log.
after all if users are complaining then you have users. Its
when they aren't complaining that you need to worry... either
your system is perfect, or you have no users ;-)
If your system is handling some critical job, it had better be
"perfect". (In fact, there are complaints, and there are
complaints. There's a very great difference between someone not
liking the background color on a monitor, and the system
crashing, and shutting down all long distance telephone services
in Germany.)
After satisfying that criteria, then I agree that doing
anything more useful is complicated. For example the user may
have asked for you to create a huge structure, but you may
have a memory leak anyway. In this case backing off and
(recursively) telling the user that their last request was too
big will be very frustrating!
That is a case I have encountered as a user, and its a very
good argument for not allocating raw pointers :-)
Or using garbage collection. In practice, the most critical
systems I've worked on have used neither garbage collection nor
smart pointers. They have used exceptionally good software
development processes, however, with effective code review,
paying particular attention to memory management issues.
I guess you also need to weigh up how much time you spend on
error feedback, versus the time you spend on adding cool new
features.
A cool new feature which disrupts telephone service on a
national level won't go over very well. A cool new feature
which means that the breaks won't apply in the locomotive won't
go over too well. A cool new feature which results in several
cellular phones being allocated the same IP address won't go
over too well.

On most of the systems I work on, the "user" never actually sees
the system, or knows what features it has. When someone in
Frankfurt calls someone in Berlin, he's (hopefully) totally
unaware that his call passes through machines that I've
programmed.
Of course the app may be a compiler. For example one of the
goals of CLANG is provide better diagnostics. Ultimately,
trying to provide useful error feedback does come to dominate
everything in many applications ( The timeline for a useful
C++ frontend is a couple of years)
http://clang.llvm.org/
For a lot of programs, error handling is most of the code. But
that can mean many different things---and hopefully, it
generally means user error handling, and not handling internal
errors in the code. (Even in the telephone applications, most
of the code was necessary to handle rerouting in case of
hardware problems. Error handling.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 8 '08 #17

P: n/a
On 7 Jan., 19:30, Grizlyk <grizl...@yandex.ruwrote:
peter koch wrote:
As i know, for each program we get at least one (hard to
detect and with random runtime apperance) error due
to improper delete/delete[] usage.
Not in idiomatic C++ where you "never" use operator delete [].

I see the Old lovely topic - a special meaning of std library in the
world :).
Not at all. You did not use the standard library which was what I
hinted you should do.
>
I suspect, you are speaking about ideal situation, where we do not use
C-style arrays or C-style arrays allocated in heap, because we are
replacing them with the help of appropreate wrappers, don't?
You use the standard elements available, e.g. std::string. This is
very good advice.
>
I think, we even can go further, and can refuse from explicit raw
memory management with new and delete, and replace all of them with
appropreate wrappers and its messages: wrapper(...), ~wrapper,
wrapper_new(...) etc.
That probably depends on your application, and often I believe you
can. But this was not what we were talking about above.
>
Let's move discussion about the ideas to some lines below.
For example, the stupid program
(http://grizlyk1.narod.ru/cpp_new/gcc/utils)
for adding source lines into gcc asm output
has 3 levels of patching of detected errors.
It is quite stupid from a C++ viewpoint as it looks
more like C. in this case, You should expect using C,
not C++ style.

"stupid from a C++ viewpoint"
Program can not be stupid due to viewpoint of concrete style or
paradigm. Stupid is just because simple, the program does nothing,
copying some lines from several files into one file.
No. The program is "stupid" because it does not use what is available
but insists on using elements of a coding style that were meant for
more low-level programming.
>
"looks more like C"?
How will you express the following code from the program with the help
of C and why:

code example
[snip]
end of code example
I am not going to spend my time determining what your code is supposed
to do, but a glimpse shows that your code is basically C, with strcpy,
fprintf and FILE*. The template is an attempt to have a "smart"
pointer to some storage perhaps? I am afraid I fail to see the purpose
of that class.
>
1. possible memory leakage.
* * * * char *const tmp=new char[len+1];
* * * * strcpy(tmp,who);
* * * * msg_copied=tmp;
* * * *}
* * * catch(...){ msg_shared="no memory"; }
"strcpy(tmp,who)" can throw while "tmp" has no owner
This is not possible so far as I know.
strcpy is C and thus does not throw.
Did you write your own strcpy?

I trust C-library in most cases, but for some situation wrappers or
even code replacement required for C-style function in C++ scope. In
the case of "strcpy", that will be comiled into "rep movsl", what kind
of replacement could be done without lost of perfomance?
Did you measure your perceived loss?
>
Often std::strcpy can produce one of SIGxxx, so the best solution is
if target C++ executable enviroment will work to convert hardware
exception into C++ exception. The other solution is explicit throwing
exception from not_std::strcpy implementation.
A SIG is not a C++ exception. Do not transform hardware exceptions
into C++ exceptions.
>
Looking at the code, it is impossible to say what kind of strcpy
implementation are used, because the code is independent from any
strcpy implementation. I think the independence is reason of
appearence of any function and especially a library.

Original code is not safe, if exception will be thrown, and modified
code is safe. Both of them can not hold on if power of CPU will be
switched off or program will be terminated by OS during strcpy
execution.
I agree, that the errors appeared due to my negligent work,
this is very bad habbit for programming, but there are many
other people with the same behaviour in the world.
This is constant fact of nature :).
Well... you can't fight bad programming in any language.

Are you think, that good programmer work only with assembler or even
directly with CPU opcodes? I guess you beleive no :). The goal of any
high-level language to reduce number of details, that must be used by
programmer simultaneously, to regroup the details into separated and
independent structures. The details with delete/delete[] look like
variable without type.
The point is that new[] is a "low-level" detail, practically never
needed in a C++ program.
>
So, the only way to prevent the errors is explicit memory
declarations:
char * ptr; * * * * * * * * *//C-style pointer
auto char * ptr; * * * * * * //can not delete/delete[]
heap char * ptr; * * * * * * //can delete heap/delete
heap[] char * msg_copied; * *//can delete heap[]/delete[]
other_memory_type char *ptr; //can delete other_memory_type
Maybe it will be added to C++.
Why? We already have std::vector (and std::string). Using either of
these would have avoided your problems.

For example, just because C-arrays are not prohibited. But speaking
seriously, we sometimes need low-level dinamic buffers for simple DTA
and so on, with special behaviour, so we can write wrappers (other
than vector<>) and use raw memory management.
I do not know what DTA is but if you can use operator new you can also
use std::vector. And if you can't use std::vector, I can't see how you
can use operator new[].
>
And returning to suspended idea about "idiomatic C++ where you never
use operator delete []".

I agree, this is not a best way to prove anything by linking to any
authority only, but some of the following ideas are quite
undestandable.

Somewhere about 90-99 years Stroustrup wrote that:

1. C++ was designed to do not insist on any concrete way of
programming. If you say, that the way is poor, you must say what
conrete thing is a problem with the way. The fact of existance of
other ways is not enough.
You did show that yourself, I believe having three errors in a 20
lines of code because you refused to use the standard library and
insisted on using lower level tools that you did not understand.
>
2. C++ was designed to be set of orthogonal, self-independed parts of
solid language, that means, that you can select and use any set of
parts you wish. If you say, that the part of language must be used
here, you must say what conrete thing is a problem without. The fact
of existance of other parts is not enough.
You can express multiplication by using addition and a for loop, but
doing so would be silly.
>
3. Library ( he was speaking about io implementation ) is _not_ a part
of C++ language. And it is right, because there are many libraries in
the world.
I am not sure I understand you here, but the C++ standard library is
very much a part of the C++ language.

I've snipped the rest of your post as I am afraid I do not quite
understand what you are trying to tell (apart that the std::library is
not part of C++ which is wrong).

/Peter
Jan 8 '08 #18

P: n/a
peter koch wrote:
>
I suspect, you are speaking about ideal situation,
where we do not use C-style arrays or C-style arrays
allocated in heap, because we are replacing them with
the help of appropreate wrappers, don't?

You use the standard elements available, e.g. std::string. This is
very good advice.
The good advice has no provements. Any simple thing is always better
than complex one. What is the problems with strXXX in the concrete
context? Nothing. The code in not intended to be reused, never.
>
"stupid from a C++ viewpoint"
Program can not be stupid due to viewpoint of concrete
style or paradigm. Stupid is just because simple,
the program does nothing, copying some lines from
several files into one file.

No. The program is "stupid" because it does not use
what is available
I think i answered on the question below:

If you say, that the part of language must be used
here, you must say what conrete thing is a problem without.
The fact of existance of other parts is not enough.
So, we will see your opinion on the idea below.
but insists on using elements of a coding style
that were meant for more low-level programming.
It is freedom, to be without strange limitations :).
"looks more like C"?
How will you express the following code
from the program with the help of C and why:

I am not going to spend my time determining
what your code is supposed to do, but a glimpse
shows that your code is basically C
Who is the grave "glimpse", that can not see templates, namespaces and
tons of C++ code :)? He is wrong.
The template is an attempt to have a "smart" pointer to some
storage perhaps?
The concrete listed template is intended to be storage for all dynamic
C-style arrays, that required inside of any block scope. The template
is owner of memory of the arrays and makes all that neccesery to
correctly return unused memory into system back.

The template has only free-stating methods, so implementation of the
template has not more overhead than ordinary POD pointer.
I am afraid I fail to see the purpose of that class.
This is very useful thing, if you need C-style array with unknown for
compile time size of the array, for non-intrusive, dynamic arrays
allocated by new[].
>
This is not possible so far as I know.
strcpy is C and thus does not throw.
Did you write your own strcpy?
In the case of "strcpy", that will be comiled into
"rep movsl", what kind of replacement could be done
without lost of perfomance?

Did you measure your perceived loss?
Sorry, It was question for which I was going to answer myself: "what
kind of replacement _could_ be done...". No, i did not measure
anything, but saw assempler output.
A SIG is not a C++ exception.
I agree.
Do not transform hardware exceptions into C++ exceptions.
I guess, you advise to do not throw from signal handler, probably? I
agree. To deliver SIGxxx to signal handler environment of executable
do some thing, that outside of C++ scope, but not prohibited by C++ to
catch excepion inside of strcpy.

At any rate, is does not matter, who can throw inside of strcpy, but
the code is ready to catch the possible exception and return the
unused memory into system back.
The details with delete/delete[] look like
variable without type.

The point is that new[] is a "low-level" detail, practically never
needed in a C++ program.
All depends from target, but if "new[]" is not prohibited, it must
work correctly. I hope, that for C++ "correct work" will be selected
instead of attacks again "new[]".
For example, just because C-arrays are not prohibited.
But speaking seriously, we sometimes need low-level
dinamic buffers for simple DTA and so on,
with special behaviour, so we can write wrappers
(other than vector<>) and use raw memory management.

I do not know what DTA is
DTA is a raw memory area for transfer data over any boundaries or used
for temporary storage.
but if you can use operator new you can also
use std::vector.
But i am not goint do use no one member of class vector<>, and the
vector<will only protect the memory from me, but i need the memory
raw accessed.
1. C++ was designed to do not insist on any concrete way of
programming. If you say, that the way is poor, you must say what
conrete thing is a problem with the way. The fact of existance of
other ways is not enough.

You did show that yourself, I believe having three errors in a 20
lines of code because you refused to use the standard library and
insisted on using lower level tools that you did not understand.
And what _exactly_ i do not understand in the concrete low level
tools? I see, you want to say, that all errors in C++ produced only by
human, in spite of compiler bring all forces to help him?

And your advice looks like you believe, that if i want to use any part
of C++, but i am not sure do i understand or do not what i am going to
do, i must select the standard library, doesn't it? Or what?

The question was: are you allowing use of other parts of language, and
if yes, why they can not be done also safe, as your lovely standard
library - is only true way to the future?
2. C++ was designed to be set of orthogonal,
self-independed parts of solid language, that means,
that you can select and use any set of parts you wish.
If you say, that the part of language must be used
here, you must say what conrete thing is a problem
without. The fact of existance of other parts
is not enough.

You can express multiplication by using addition
and a for loop, but doing so would be silly.
I do not understand, i did not use "addition and for loop". What is
concrete problem in my example without unused parts (excluding errors
already detected by me).
3. Library ( he was speaking about io implementation )
is _not_ a part of C++ language. And it is right,
because there are many libraries in
the world.

I am not sure I understand you here, but the C++ standard
library is very much a part of the C++ language.
All is quite clear. Type "int" is a part of language, but function
"printf" is not. The "printf" is member of a ordinary library, but the
library is standard, so you can think, that the library will exist and
your code will be portable and understandable for other readers.

Maksim A. Polyanin
old page about some C++ improvements:
http://grizlyk1.narod.ru/cpp_new
Jan 9 '08 #19

P: n/a
On 9 Jan., 04:03, Grizlyk <grizl...@yandex.ruwrote:
peter koch wrote:
I see the Old lovely topic - a special meaning
of std library in the world :).
Not at all. You did not use the standard library which was what I
hinted you should do.

I like it, let's go :).
[snip]
I really do not want to talk to much about performance. Any competent
programmer knows that performance problems are best solved by
profiling code and removing bottlenecks. This is especially true when
you find code with three errors in 20 lines and programmers that do
not know when to use delete and when to use delete []. Use the
standard libraries, measure and rewrite where you have to - if need be
by replacing e.g. standard containers by your own product (though I do
not remember when that gave any speed-up worth mentioning).

But since you seem so obsessed with performance, I believe it would
serve you better to give us some examples where std::vector is unable
to keep up with the performance of your home-grown class. You
certainly must have spent some time profiling std::vector and your own
alt_vector so that you can tell us ignorant fools what the secret
behind your alt-vector is.

/Peter
Jan 9 '08 #20

P: n/a
On 9 Jan., 05:50, Grizlyk <grizl...@yandex.ruwrote:
peter koch wrote:
I suspect, you are speaking about ideal situation,
where we do not use C-style arrays or C-style arrays
allocated in heap, because we are replacing them with
the help of appropreate wrappers, don't?
You use the standard elements available, e.g. std::string. This is
very good advice.

The good advice has no provements. Any simple thing is always better
than complex one. What is the problems with strXXX in the concrete
context? Nothing. The code in not intended to be reused, never.
What is wrong with the code is that you are using three lines of code
where one should suffice and that your code risks a buffer-overflow.
And this in a section of code, where performance of code matters
zilch.
Apart from that, my guess is that the std::string approach would be
faster than your homegrown code.

[snip]
>
So, we will see your opinion on the idea below.
but insists on using elements of a coding style
that were meant for more low-level programming.

It is freedom, to be without strange limitations :).
It is freedom being without limitations which obviously you don't seem
to have. You are just not using your freedom wisely, but what can one
expect from a russian? ;-)
>
"looks more like C"?
How will you express the following code
from the program with the help of C and why:
I am not going to spend my time determining
what your code is supposed to do, but a glimpse
shows that your code is basically C

Who is the grave "glimpse", that can not see templates, namespaces and
tons of C++ code :)? He is wrong.
A template and a namespace does not do it. Sorry.
>
The template is an attempt to have a "smart" pointer to some
storage perhaps?

The concrete listed template is intended to be storage for all dynamic
C-style arrays, that required inside of any block scope. The template
is owner of memory of the arrays and makes all that neccesery to
correctly return unused memory into system back.
Something that std::vector does perfectly.
>
The template has only free-stating methods, so implementation of the
template has not more overhead than ordinary POD pointer.
Should I interpret the above to mean that you believe that member
functions cause any overhead? Sorry - you are wrong again.
>
I am afraid I fail to see the purpose of that class.

This is very useful thing, if you need C-style array with unknown for
compile time size of the array, for non-intrusive, dynamic arrays
allocated by new[].
Again, std::vector does this just as well and just as efficiently.
This is not possible so far as I know.
strcpy is C and thus does not throw.
Did you write your own strcpy?
In the case of "strcpy", that will be comiled into
"rep movsl", what kind of replacement could be done
without lost of perfomance?
Did you measure your perceived loss?

Sorry, It was question for which I was going to answer myself: "what
kind of replacement _could_ be done...". No, i did not measure
anything, but saw assempler output.
So you measured nothing. Actually, I am not surprised.
>
A SIG is not a C++ exception.

I agree.
Do not transform hardware exceptions into C++ exceptions.

I guess, you advise to do not throw from signal handler, probably? I
agree. To deliver SIGxxx to signal handler environment of executable
do some thing, that outside of C++ scope, but not prohibited by C++ to
catch excepion inside of strcpy.

At any rate, is does not matter, who can throw inside of strcpy, but
the code is ready to catch the possible exception and return the
unused memory into system back.
The details with delete/delete[] look like
variable without type.
The point is that new[] is a "low-level" detail, practically never
needed in a C++ program.

All depends from target, but if "new[]" is not prohibited, it must
work correctly. I hope, that for C++ "correct work" will be selected
instead of attacks again "new[]".
New works perfectly and is not prohibited, there's just no use for it.
>
For example, just because C-arrays are not prohibited.
But speaking seriously, we sometimes need low-level
dinamic buffers for simple DTA and so on,
with special behaviour, so we can write wrappers
(other than vector<>) and use raw memory management.
I do not know what DTA is

DTA is a raw memory area for transfer data over any boundaries or used
for temporary storage.
std::vector is perfect for "DTA".
but if you can use operator new you can also
use std::vector.

But i am not goint do use no one member of class vector<>, and the
vector<will only protect the memory from me, but i need the memory
raw accessed.
Which you can get.
>
1. C++ was designed to do not insist on any concrete way of
programming. If you say, that the way is poor, you must say what
conrete thing is a problem with the way. The fact of existance of
other ways is not enough.
You did show that yourself, I believe having three errors in a 20
lines of code because you refused to use the standard library and
insisted on using lower level tools that you did not understand.

And what _exactly_ i do not understand in the concrete low level
tools? I see, you want to say, that all errors in C++ produced only by
human, in spite of compiler bring all forces to help him?

And your advice looks like you believe, that if i want to use any part
of C++, but i am not sure do i understand or do not what i am going to
do, i must select the standard library, doesn't it? Or what?
My advice is to use the standard library. If the standard library does
not do what you want fast enough (and if you are sure you understand
the standard library and use it correctly), you can try to roll wour
own specialisation and see it it helps.
>
The question was: are you allowing use of other parts of language, and
if yes, why they can not be done also safe, as your lovely standard
library - is only true way to the future?
Use safe features first. A program is worth nothing it does not work
correctly and using unsafe constructs is one way to spend time testing
rather than developing.
>
2. C++ was designed to be set of orthogonal,
self-independed parts of solid language, that means,
that you can select and use any set of parts you wish.
If you say, that the part of language must be used
here, you must say what conrete thing is a problem
without. The fact of existance of other parts
is not enough.
You can express multiplication by using addition
and a for loop, but doing so would be silly.

I do not understand, i did not use "addition and for loop". What is
concrete problem in my example without unused parts (excluding errors
already detected by me).
With C++ you have a nice toolbox, but to me it seems you're only using
the hammer. This is not an efficient way to program.
>
3. Library ( he was speaking about io implementation )
is _not_ a part of C++ language. And it is right,
because there are many libraries in
the world.
I am not sure I understand you here, but the C++ standard
library is very much a part of the C++ language.

All is quite clear. Type "int" is a part of language, but function
"printf" is not. The "printf" is member of a ordinary library, but the
library is standard, so you can think, that the library will exist and
your code will be portable and understandable for other readers.
That is wrong. printf (to use a bad example) is part of the C++
standard library.

/Peter
Jan 9 '08 #21

P: n/a
On Jan 8, 11:03*am, James Kanze <james.ka...@gmail.comwrote:
On Jan 6, 9:19 am, kwikius <a...@servocomm.freeserve.co.ukwrote:
On Jan 5, 6:53 pm, James Kanze <james.ka...@gmail.comwrote:
You have very tolerant users.
It could be other applications on the system,

It's a dedicated system. *There aren't (or shouldn't be) any
other "applications".
Disallowing other applications greatly simplifies the design for
sure ;-).

<...>
We have logs, we can change the log configuration without
stopping the process, and we can even ftp into the users machine
to recover the log.
If your system is handling some critical job, it had better be
"perfect".
<...>

In a perfect system, logs should surely be unnecessary?

Perfect systems only exist as simplifications for theoretical proofs.
Every real system is imperfect.
:-)
Jan 10 '08 #22

P: n/a
On Jan 10, 12:17*am, kwikius <a...@servocomm.freeserve.co.ukwrote:
On Jan 8, 11:03*am, James Kanze <james.ka...@gmail.comwrote:
On Jan 6, 9:19 am, kwikius <a...@servocomm.freeserve.co.ukwrote:
On Jan 5, 6:53 pm, James Kanze <james.ka...@gmail.comwrote:
You have very tolerant users.
It could be other applications on the system,
It's a dedicated system. *There aren't (or shouldn't be) any
other "applications".

Disallowing other applications greatly simplifies the design for
sure ;-).

<...>
We have logs, we can change the log configuration without
stopping the process, and we can even ftp into the users machine
to recover the log.
............

Apologies. I should have added a break here

.............

<...>

If your system is handling some critical job, it had better be
"perfect".

<...>

regards
Andy Little

Jan 10 '08 #23

P: n/a
In article <d0464701-67dc-48cd-9503-250faf6da808
@p69g2000hsa.googlegroups.com>, ja*********@gmail.com says...

[ ... ]
The cost of this dead code is relatively low though -- it's
stored on disk, but if it's never used, it may never even be
paged into physical memory.

It's less than that: the functions which implement it are
templates, which aren't instantiated unless they are used.
Potentially used -- I was thinking of a case where you used push_back on
your vector, but in every case had used reserve up-front to ensure that
the push_back would never reallocate the vector. Even though the
reallocation will never be called, the linker won't (normally) be able
to determine that, so it'll get compiled in even though it's never used.
[...]
At least with the compilers I've tested so far, std::sort is
consistently at least twice as fast as qsort. std::sort on an array is
sometimes faster than std::sort on a vector -- but sometimes it's
slower. I'm pretty sure you'd have to do the test extremely carefully
(and often) to be sure whether there's a statistically significant
difference between the two. Even if there is a difference, I'm quite
certain it's too small to care about most of the time.

If there is a difference, then it will depend on the compiler
and the architecture. One may be faster with one compiler or
architecture, and slower with another.
True -- my point wasn't that array can't ever be faster (in fact, I know
of one compiler on Windows were it is) but that you can't depend on it
being faster -- I also know of one compiler on Windows where sorting the
vector (with the code I posted previously) is roughly twice the speed of
sorting the array.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jan 15 '08 #24

P: n/a
* Jerry Coffin peremptorily fired off this memo:
True -- my point wasn't that array can't ever be faster (in fact, I know
of one compiler on Windows were it is) but that you can't depend on it
being faster -- I also know of one compiler on Windows where sorting the
vector (with the code I posted previously) is roughly twice the speed of
sorting the array.
How come nobody ever names the compilers? I'd like to know more about
the tools I might use!

--
There is no likelihood man can ever tap the power of the atom.
-- Robert Millikan, Nobel Prize in Physics, 1923
Jan 15 '08 #25

P: n/a
In article <WI******************@bignews6.bellsouth.net>,
li*****@bollsouth.nut says...
* Jerry Coffin peremptorily fired off this memo:
True -- my point wasn't that array can't ever be faster (in fact, I know
of one compiler on Windows were it is) but that you can't depend on it
being faster -- I also know of one compiler on Windows where sorting the
vector (with the code I posted previously) is roughly twice the speed of
sorting the array.

How come nobody ever names the compilers? I'd like to know more about
the tools I might use!
In this case because the compiler was more or less beside the point.
Since you care, however, most of the MS compilers I have handy produce
code that seems to run the same speed for both an array and a vector.
g++ (3.4.4) produces code that's substantially slower for a vector than
an array. Comeau produces code that's about twice as fast for a vector
as an array (and, incidentally, the code it produces for an array is
still faster than anybody else produces. That's with Comeau using
Microsoft as its back-end -- I haven't really tried this particular test
with a lot of other back-ends.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jan 16 '08 #26

P: n/a
Jerry Coffin wrote:
>
I assume you say about C-style array. But i have said about an
abstract array. The concrete concept of abstract array can be not
equal to C-style array.

Are you saying you want to compare vector to something
that exists only in your imagination?
Do you really not understand what is "abstract array"? (I do not
insist on answer).
I have said about object-oriented paradigm only. For the
paradigm (supported by C++) the digging of any
implementation is not allowed.

digging? I'm not sure what you're trying to say here.
Do you really can not make a noun with "ing" from verb "dig"? (I do
not insist on answer).

I saw a man in the group, who believe, that templated source can be
compiled with pure C language. And so on.

I think, any man, who are not going to asnwer for his words and allows
to himself to do anywhing what he want, is not a best company to
discuss anything. At least because the kind of man will never limit
himself only by the C++ questions and the habit will be applied by him
for anything, that is why the result of the application will be ugly
and often unexpected for any other poor listener aside, who will
believe to the honest man :).

And yet, dear experts and users of stl++ and boost++ programming
languages. Take in account, there are no other group to discuss C++
questions. Note, that comp.lang.c++ is not the same as group to learn C
++ and to discuss only a certain styles of C++ programming.

I can not trace the group comp.lang.c++ day by day so i can ask time
by time some questions, in hope to find a concrete readers, who will
be able to understand the question about, and no more - i am ready to
get answers from anybody, but do not insist to answer for anybody :).

Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new
Jan 18 '08 #27

P: n/a
In article <4b3ec2d2-6e7e-4ef1-89d3-
63**********@v67g2000hse.googlegroups.com>, gr******@yandex.ru says...

[ ... ]
I think, any man, who are not going to asnwer for his words and allows
to himself to do anywhing what he want, is not a best company to
discuss anything.
I agree.

Plonk!

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jan 19 '08 #28

This discussion thread is closed

Replies have been disabled for this discussion.