![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
[an error occurred while processing this directive]
12.2 Use other C mem... routines on objects allocated with new?Problem A plethora of functions is available in the C header files string.h and mem.h. Functions such as memcpy() and memmove() are handy, and it would be nice to confirm whether it is possible to use them in C++. Technique Yes, its possible to use the C memory manipulation functions. Most of the mem... functions take void pointers as arguments, which are generic memory references that are not managed by the memory manager. For instance, this C++ code snippet is perfectly valid, assuming that the header files are C++ safe. (That is, that they have been appropriately modified for use with a C++ compiler. Its safe to say that all header files that come with your C++ system are correct.) #include <string.h> ... char* MyMemory = new char[1500]; memset(MyMemory, 0, 1500); delete[] MyMemory; Of course, production code would wrap the allocation in a try { ... } catch sequence to make sure the call to new was successful before calling memset(). How It Works After a pointer exists, functions that do not have anything to do with memory allocation or de-allocation work the same way they did in C. Comments It is useful to peruse the header files for the C functions you want to use in your programs, because many compiler vendors have extended the C++ versions to include default arguments. Because C++ implements much stricter type checking than C, its also useful to know the specific types. Unlike C, for instance, the char and int types cannot be interchanged, and doing so will cause some compiler warning messages. 12.3 Find out how much memory my structures and classes really take?Problem Sometimes it is not readily apparent how much actual memory an object uses. This is especially important to understand when moving data formats between 16- and 32-bit platforms. Technique Instantiated classes take the same amount of space as all their data members, which is system dependent. On 32-bit systems, each integer, unsigned int, and pointer takes 4 bytes, chars take 1 byte, unicode chars take 2 bytes, and floats are 4 bytes, doubles are 8 bytes, and long doubles are 10 bytes on Intel processor machines. This is by no means the end of it. The byte alignment setting on your compiler modifies the real amount of memory your structures and classes take. Some compilers default to specific settings, and others allow complete control over this setting. Byte Alignment Your compiler will likely have settings for byte alignment. These options can increase the performance of your programs on some processors, because most processors incur a sometimes-significant performance penalty when they are fetching data that does not end on their alignment boundary. For instance, the Intel 486 processor uses a 32-bit data bus. When fetching a 16-bit integer (an int in DOS and 16-bit Windows), it actually fetches the whole 32 bits of memory. Further, from the processors point of view the memory is actually divided into 1/4 of the actual bytes of memory available (4 bytes = 2 16-bit words). Even the 32-bit Intel processors refer to one 32-bit value as a double word or DWORD, and the processor can only retrieve data based on these boundaries. This might not seem significant at first glance, but take a moment to think through the following example. If the integer is a structure or class like this struct { char MyChar ; long int myLongInt ; } MyStruct ; when your program is byte-aligned (the smallest granularity possible on a PC), the computer (assuming it is a 386DX or later processor) will fetch the 32-bit region containing MyChar when the member is referenced. It will then shuffle the bits around appropriately to allow your program to work with the variable. One time out of four the structure will line up correctly, but the rest of the time the computer will have to do some work to make it possible for this variable to be worked with. When fetching MyLongInt, there is a 50% percent chance the system will have to fetch only one 32-bit word to get all of MyLongInt. The other 50% of the time, it will have to do 2 fetchesfirst it gets the least significant bytes, and then the most significant bytes, and then shuffles the data to get one 32-bit integer. If you think this has to be slower, youre absolutely right. It adds a lot of overhead. There are other byte-alignment issues as well. Most code starting points (for example, functions) perform best when started on these 4-byte boundaries, and little performance gains can add up quickly. If the structure were aligned on a 4-byte boundary, MyChar would start on a 4-byte boundary, and myLongInt would also, and there would be 24 bits of wasted space between the two, meaning the actual struct would be 8 bytes, rather than 5 bytes in size. With the preceding in mind, envision the following development scenario: Two groups of developers have to make binary files transportable between their respective applications. To that end, they share some header files that define the structures the programs use. If one group used 2-word (4 bytes) byte alignment in its compiled application, and the other one did not, their structure sizes are not likely to match when the data is read back from the file. The result will likely be that some poor programmer has to dig through code that might be just fine, only to discover at some point that the actual structure sizes written to disk differ. How can a programmer account for this? For the most part, it involves some knowledge about the development system and operating system in use. Just knowing C++ is not enough when these machine- and OS-dependent issues come into play. If youre working with outside code, especially executables, its tough to find out what the byte alignment setting was.
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|