Skip to main content
GameDev.net gamedev.net
🔒 Locked

new and delete

Started by TelevirtualSoftDev Aug 24, 2006 at 5:06 AM 22 replies 2.7k views
Original Post
TelevirtualSoftDev
TelevirtualSoftDev
Hi, Does anyone know of and reason why new and delete must be in the same class?. My code contains this: char* cAsciiArrayPtr = NULL; cAsciiArrayPtr = arrayCopier.copyToCharArray(argv[1]); (the 'new' is in here) cAsciiArrayPtr = NULL; delete[] cAsciiArrayPtr; I can't see why it would cause a memory leak but I just thought I'd check it out. Is there an easy way to check for memory leaks when degugging with Microsoft Visual C++?
BigBadBob
BigBadBob
It will leak because the delete [] is doing nothing as you are NULLing the pointer before hand. Do the delete [] first and then NULL the pointer.

As for checking for memory leaks, look up _CrtDumpMemoryLeaks()
TelevirtualSoftDev
TelevirtualSoftDev

Sorry, silly mistake...thanks for pointing it out though.

It should read:

char* cAsciiArrayPtr = NULL;

cAsciiArrayPtr = arrayCopier.copyToCharArray(argv[1]); (the 'new' is in here)

delete[] cAsciiArrayPtr;
cAsciiArrayPtr = NULL;

thanks for the other tip to...i'll look into it.
snk_kid
snk_kid
Quote:
Original post by TelevirtualSoftDev

Sorry, silly mistake...thanks for pointing it out though.

It should read:

char* cAsciiArrayPtr = NULL;

cAsciiArrayPtr = arrayCopier.copyToCharArray(argv[1]); (the 'new' is in here)

delete[] cAsciiArrayPtr;
cAsciiArrayPtr = NULL;

thanks for the other tip to...i'll look into it.


Any particular reason for not using the standard library string type? (std::basic_string, type alias std::string).
TelevirtualSoftDev
TelevirtualSoftDev

I'm feeding the char array into an API for a Text to Speech engine which doesn't like it.
snk_kid
snk_kid
Quote:
Original post by TelevirtualSoftDev

I'm feeding the char array into an API for a Text to Speech engine which doesn't like it.


When dealing with (legacy) APIs that expect C style strings (which do not modify there arguments) then you use the method std::basic_string::c_str and pass it off to that function/method.
Aardvajk
Aardvajk
Just to answer your question though, assuming arrayCopier.copyToCharArray returns some memory allocated with new, there is no problem deleting the pointer outside of the arrayCopier class.

Just make sure you know whether you have allocated an array or a single item in order to call the correct delete ptr or delete [] ptr.

That's not to say you shouldn't take snk_kid's advice and use std::string in this example, just to provide an answer to your actual question.
AbandonedAccount
AbandonedAccount
Doesn't string::c_str return a const char*? If so, it is not equivalent to code which returns a char*.

To answer the original question of whether there will be a memory leak, one really must see the calls to new and delete. Without that, people can speculate that "if your unposted code is correct" you do not have a memory leak. This assumption virtually defeats the purpose of your question.

If you ever wish to test code for memory leaks, you can just wrap it in a loop that executes it perhaps a million times. If your program starts using more memory, there's probably a problem. I strongly recommend learning to test your code thoroughly.
snk_kid
snk_kid
Quote:
Original post by richardurich
Doesn't string::c_str return a const char*? If so, it is not equivalent to code which returns a char*.


Yes if you look back to what i wrote i said that implicitly, most (legacy) APIs that take C-style strings do not modify there arguments. Some legacy APIs that take C-style strings are not constant correct yet again do not actually modify there arguments and is typically documented hence it's acceptable (just about) to use a constant cast (i.e. const_cast).

For all other cases you will need to make a separate copy but TelevirtualSoftDev is reinventing wheels anways since you can/should use std::copy or at very least std::strcpy/strncpy.
Bregma
Bregma
Quote:
Original post by snk_kid
For all other cases you will need to make a separate copy but TelevirtualSoftDev is reinventing wheels anways since you can/should use std::copy or at very least std::strcpy/strncpy.


Nay, for all other cases you should used vector. For gosh sake, if all you need is a vector of type char, use a vector of type char and stick with the native idioms.
  #include <cstring>  #include <vector>  // ...  std::vector<char> asciiArray(argv[1], argv[1]+std::strlen(argv[1]));  legacyCallTaskingCharPointers(&asciiArray[0]);
Stephen M. Webb
Professional Free Software Developer
snk_kid
snk_kid
Quote:
Original post by Bregma
Quote:
Original post by snk_kid
For all other cases you will need to make a separate copy but TelevirtualSoftDev is reinventing wheels anways since you can/should use std::copy or at very least std::strcpy/strncpy.


Nay, for all other cases you should used vector. For gosh sake, if all you need is a vector of type char, use a vector of type char and stick with the native idioms.
  #include <cstring>  #include <vector>  // ...  std::vector<char> asciiArray(argv[1], argv[1]+std::strlen(argv[1]));  legacyCallTaskingCharPointers(&asciiArray[0]);


Yes good point however you could make it better time complexity wise if you use std::string from the begining.

#include <string>#include <vector>#include <algorithm>// .....std::string s = argv[1];// ....std::vector<char> cs(s.length() + 1);std::copy(s.begin(), s.end(), cs.begin());cs[s.length()] = '\0';legacyAPIFunction(&cs[0]);


[Edited by - snk_kid on August 24, 2006 2:04:50 PM]
Zahlman
Zahlman
Quote:
Original post by snk_kid
Quote:
Original post by Bregma
Quote:
Original post by snk_kid
For all other cases you will need to make a separate copy but TelevirtualSoftDev is reinventing wheels anways since you can/should use std::copy or at very least std::strcpy/strncpy.


Nay, for all other cases you should used vector. For gosh sake, if all you need is a vector of type char, use a vector of type char and stick with the native idioms.


Yes good point however you could make it better time complexity wise if you use std::string from the begining.


Uh, they both look O(n) to me :s
Bregma
Bregma
Quote:
Original post by snk_kid
Yes good point however you could make it better time complexity wise if you use std::string from the begining.

#include <string>#include <vector>// Allocates O(strlen(argv[1])) chars, copies strlen(argv[1]) chars from argv[1] into s.std::string s = argv[1];// Allocates s.length()+1 chars, initializaes them to 0.std::vector<char> cs(s.length() + 1);// Copies s.length() chars from s into cs.std::copy(s.begin(), s.end(), cs.begin());// Sets the EOS.  Note it's already zero.cs[s.length()] = '\0';legacyAPIFunction(&cs[0]);


Hmm, sounds like twice as many memory allocations and copies over just using the vector.

I would suggest that creating a vector and then using copy is more work (for me) than just creating the vector using the range constructor. My time is money, and more work means higher cost.

Stephen M. Webb
Professional Free Software Developer
ordered_disorder
ordered_disorder
Quote:
Original post by snk_kid
Quote:
Original post by Bregma
Quote:
Original post by snk_kid
For all other cases you will need to make a separate copy but TelevirtualSoftDev is reinventing wheels anways since you can/should use std::copy or at very least std::strcpy/strncpy.


Nay, for all other cases you should used vector. For gosh sake, if all you need is a vector of type char, use a vector of type char and stick with the native idioms.
  #include <cstring>  #include <vector>  #include <algorithm>  // ...  std::vector<char> asciiArray(argv[1], argv[1]+std::strlen(argv[1]));  legacyCallTaskingCharPointers(&asciiArray[0]);


Yes good point however you could make it better time complexity wise if you use std::string from the begining.

#include <string>#include <vector>// .....std::string s = argv[1];// ....std::vector<char> cs(s.length() + 1);std::copy(s.begin(), s.end(), cs.begin());cs[s.length()] = '\0';legacyAPIFunction(&cs[0]);


How in the world is that more faster than just using a vector in the beginning? Seems like nearly twice as many allocations and copies compared to just using a vector. Then again if speed is issue and(&&) your a good programmer, just using a fusking char *. Though this looks like a high level case where it will save you programming time and possible headache time just using a straight vector.
snk_kid
snk_kid
Quote:
Original post by Zahlman
Uh, they both look O(n) to me :s


I'm alluding to many things here, look closely at strlen if you're not going to maintain this vector of chars and you're going to do this on a regular basis you're paying an extra O(n) for strlen each time because strlen is not a constant time operation, where as my example is sacrificing a minute & insignicant amount of memory, allocated just once (instead of using argv) for time. This is what the "..." was implying. if you're just doing this on a one-off then it's not worth it.

Quote:
Original post by Bregma
Hmm, sounds like twice as many memory allocations and copies over just using the vector.


Not exactly, read what i just wrote to Zahlman above.

Quote:
Original post by Bregma
I would suggest that creating a vector and then using copy is more work (for me) than just creating the vector using the range constructor. My time is money, and more work means higher cost.


There is no need to be so condescending, beside the point what you said about saving time is a little exaggerated because if that was the case you wouldn't be using C++ to begin with. Are you implying that C++ is a highly prodcutive & elegant langauge? well it isn't.

Honestly, don't post for some time comeback and this is the result.

[Edited by - snk_kid on August 24, 2006 12:44:22 PM]
ordered_disorder
ordered_disorder
Quote:
Original post by snk_kid
Quote:
Original post by Zahlman
Uh, they both look O(n) to me :s


I'm alluding to many things here, look closely at strlen if you're not going to maintain this vector of chars and you're going to do this on a regular basis you're paying an extra O(n) for strlen each time because strlen is not a constant time operation, where as my example is sacrificing a minute & insignicant amount of memory, allocated just once (instead of using argv) for time. This is what the "..." was implying. if you're just doing this on a one-off then it's not worth it.


One strlen, one allocation and one copy, doesn't seem as costly as two copies, two allocations and the overhead of a vector and string. We're talking miniscule overhead in either case, but IF we are going to make the comparisons.

There's also the readability coefficient.

*EDITED FOR POOR WORDING*
snk_kid
snk_kid
Quote:
Original post by ordered_disorder
One strlen, one allocation and one copy, doesn't seem as costly as two copies, two allocations and the overhead of a vector and string. We're talking miniscule overhead in either case, but IF we are going to make the comparisons.

There's also the readability coefficient.

*EDITED FOR POOR WORDING*


Since you're not bothering to read carefully i'm not going to bother acknowledging your comments.
ordered_disorder
ordered_disorder
Quote:
Original post by snk_kid
Since you're not bothering to read carefully i'm not going to bother acknowledging your comments.


Uh, I am not attacking you, my wording implies that my statement is what I think, not what I know. If I misread what you said, maybe you should point out where am I wrong instead of taking this pompous attitude. I certainly tried to comprehend what you were saying.
Zahlman
Zahlman
Quote:
Original post by snk_kid
Quote:
Original post by Zahlman
Uh, they both look O(n) to me :s


I'm alluding to many things here, look closely at strlen if you're not going to maintain this vector of chars and you're going to do this on a regular basis you're paying an extra O(n) for strlen each time because strlen is not a constant time operation, where as my example is sacrificing a minute & insignicant amount of memory, allocated just once (instead of using argv) for time. This is what the "..." was implying. if you're just doing this on a one-off then it's not worth it.


It took me a hell of a long time to figure out what you were saying here.

It sounds like you're arguing that you can keep the string instance around and thereby save on the cost of converting to a vector by relying on the string's cached length information. (Every other interpretation I thought of is far more ridiculous.)

But...

why not just keep the *vector* around? :P
Bregma
Bregma
Quote:
Original post by snk_kid
Quote:
Original post by Bregma
I would suggest that creating a vector and then using copy is more work (for me) than just creating the vector using the range constructor. My time is money, and more work means higher cost.


There is no need to be so condescending, beside the point what you said about saving time is a little exaggerated because if that was the case you wouldn't be using C++ to begin with. Are you implying that C++ is a highly prodcutive & elegant langauge? well it isn't.


I apologise for coming across as condescending.

As a professional C++ programmer, saving my time both during development and later during maintenance is a primary consideration. Both my solution and your solution are functionally equivalent (even if yours has twice the allocations and twice the number of passes over the data, count 'em again). Mine has a single line of code, which is faster to type and if you're familiar with the C++ idiom of range construction, faster to grasp at a glance.

I would take issue with your statement that C++ is not a productive and elegant programming language, but I think that's subjective and I have better things to do with my time other than a is-too/is-not repartee.
Stephen M. Webb
Professional Free Software Developer

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.