Solved

"new" operator

Posted on 1998-02-20
12
178 Views
Last Modified: 2010-04-10
I have a statement

char * cKey = new char[iKeyLen];

where iKeyLen is a const int equal to 18.  Can anyone tell me why this statement always initializes cKey to a length of 22 instead of 18 and how to correct it?
0
Comment
Question by:dirtdart
  • 7
  • 4
12 Comments
 
LVL 5

Author Comment

by:dirtdart
ID: 1182651
Edited text of question
0
 
LVL 3

Expert Comment

by:q2guo
ID: 1182652
dirtdart: How do you know cKey was initialized to a length of 22?
0
 
LVL 22

Accepted Solution

by:
nietod earned 200 total points
ID: 1182653
answer coming.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1182654
What I assume you are refering to is the fact that the new operator calls some sort of allocation procedure (usually malloc()) and requests that it allocates 22 bytes, rather than 18.  

Whenever you allocate an array ("new []" as opposed to just "new") it will alocate 4 extra bytes (in a 32 but environment).  These 4 extra butes are used to record the number of array elements.  This is used when the array is deleted with "delete []"  The delete operator will look up the number of elements in the array so it can call the destructor for each object in the array.  Remeber when you allocate with "new []" you specify the number of items so "new []" knows how many times it needs to construct.  "delete []" on the other hand doesn't get a number of elements (anymore, originally it did!) so it needs this embedded count to help it.

Note something important.  The pointer you get back does not point to this count.  It points past it.  The new oeprator will set the count at the start of the memory allocated then return a pointer to you that is past the count.  Delete will take the pointer you give it and subtract 4 to get a pointer to the count and to the memory to dispose.

Make sense?
0
 
LVL 5

Author Comment

by:dirtdart
ID: 1182655
That makes sense, but I'm not sure it helps.

Two reasons I know it was 22 bytes.  First, I had the memory watch window open during the process.  Second, I did a strlen(cKey) and was returned 22.

This would not normally be a problem, except that when I use it, these 4 bytes are being appended to the end of my string. Here's the situation.

When I initalize the string with new, it initializes the memory in question to 18 hex characters 0xCD and four hex characters 0xFD.  I then use strncpy to copy the information I need into the newly created string buffer.  When the strncpy returns, I have my copied string, but it still has the four 0xFD characters appended to the end, which makes it totally unusable to my program.  I know these aren't hang over characters from another string, because in the memory watch, the entire area is empty (0x00) until new is called.

I have also run into another situation in which I allocate a 4 byte string with new, and it returns as 5.  I mainly just need a way to get rid of the offending characters on the end.  Preferably to make sure they aren't there in the first place.  If these are internal pointers telling delete how many characters to delete, that is fine, but they shouldn't show up in the string value.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1182656
Allright, ignore everything I said.  (Actually everythign I said was true, but is not what you discovered.)  
I assume from the information you just gave you are working in a debug version.  The debug version of Microsoft VC (maybe other C's) initializes dynamically allocated memory to 0xCD.  This is not done in release versions.  In release versions the memory contains random values depending on how it was previously used.  The debug performs this initialization so that it obvious to you if you are using memory that you haven't initialized yet.  It also sets 4 bytes (I'm not sure of the number, but you see 4 so that's probably it.) before the memory and 4 bytes after the meory to 0xFD.  This is to insure that you don't go past the ends of the memory you requested a common and serious bug.  If you write past the ends of the memory and corrupt these bytes it will detect this on "delete" and warn you.

more coming.
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 22

Expert Comment

by:nietod
ID: 1182657
Now the 0xFD bytes should not be considered part of the string.  The string, that is, the memory that belongs to the string, should be considered to end before those bytes.  You should see a NUL terminator before those bytes.  If you don't see a NUL (a zero byte) you are doing something wrong that is preventing it from appearing.  Most likely what you are doing wrong is using strncpy().  strncpy() is the most useless function in the C library.  If your source string is longer than the number of characters you specifiy (the desination length), then it copies the number you specify and does not put in a NUL terminator (there is no room).  That is stupid!  It should copy one less than the length you specify and put in a NUL.  Things get worse if the source is shorter than the destination.  It that case it doesn't put in just one NUL terminator.  It pads the entire destination with as many NUL terminators as will fit.  That is a waste of time as you need only one!  

Solution.  Don't use strncpy().  Write your own.  Or switch to using a reference counted string class.  Reference counted strings classes make pogramming MUCH easier and safer and they usually do not slow down processing (there are many cases where they can speed things up.)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1182658
I don't know if I need to mention this or not, but when you allocate memory for a string you need to allocate room fo the terminator.  To allocate a 4 character string, you need to allocate 5 bytes, for example

char *abcdptr = new char[5];

strcpy(abcdptr,"ABCD")

if you allocate only 4 characters, the NUL terminator will be placed after the end of the memory you requested.  This will not be detected in a release version and may cause serious problems.
0
 
LVL 5

Author Comment

by:dirtdart
ID: 1182659
You know, I knew about the null termination on the strings, but I wasn't even thinking about it when using new.  I guess all I really need to do to fix this is add one to the length when declaring the string originally.  That will leave room for the null terminator.  Thank you for your concise and well thought out answer.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1182660
Concise and well thought out?  I missed with 2 out of 3 long comments!

Yes, all you need to do is allocate one more byte and your problems will go away. (I guess not all your problems, but these.)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1182661
I'm posting this comment to this question to let you know that I think Mike is way out of line with the comment he made on your multithreading question.  Your comment was probably just poorly worded.  At worst it was made in ignorance -- from a "novice" seeking help.  It certainly did not deserve the comment he made.  I don't know what is up with him.  He is usually very helpful.  But right now he seems to be going around and insulting and criticising everyone.  (Sometime the criticism is right, but the way he is making it isn't. In this case, the criticism wasn't even the least bit fair.)  I didn't want to post a comment on that question, because I don't want this to get into a fighting match.
0
 
LVL 5

Author Comment

by:dirtdart
ID: 1182662
I don't know if he was offering that as criticizsm or simply asking an opinion.  I treated it as asking it for an opinion.  Thanks for not trying to start a fight over it.  I've seen too many of those (and been involved in a couple) around here, and it just isn't worth it.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now