Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

ANSI/ISO C++ Professional Programmer''''s Handbook phần 9 pot
Nội dung xem thử
Mô tả chi tiết
Put differently, the statement
C* p = new C;
is transformed by the compiler into something similar to the following:
#include <new>
using namespace std;
class C{/*...*/};
void __new() throw (bad_alloc)
{
C * p = reinterpret_cast<C*> (new char [sizeof ]); //step 1: allocate
// raw memory
try
{
new (p) C; //step 2: construct the objects on previously allocated buffer
}
catch(...) //catch any exception thrown from C's constructor
{
delete[] p; //free the allocated buffer
throw; //re-throw the exception of C's constructor
}
}
Alignment Considerations
The pointer that is returned by new has the suitable alignment properties so that it can be converted to a pointer of
any object type and then used to access that object or array. Consequently, you are permitted to allocate character
arrays into which objects of other types will later be placed. For example
#include <new>
#include <iostream>
#include <string>
using namespace std;
class Employee
{
private:
string name;
int age;
public:
Employee();
~Employee();
};
void func() //use a pre allocated char array to construct
//an object of a different type
{
char * pc = new char[sizeof(Employee)];
Employee *pemp = new (pc) Employee; //construct on char array
//...use pemp
pemp->Employee::~Employee(); //explicit destruction
ANSI/ISO C++ Professional Programmer's Handbook - Chapter 11 - Memmory Management
file:///D|/Cool Stuff/old/ftp/1/1/ch11/ch11.htm (11 von 23) [12.05.2000 14:46:34]
delete [] pc;
}
It might be tempting to use a buffer that is allocated on the stack to avoid the hassle of deleting it later:
char pbuff [sizeof(Employee)];
Employee *p = new (pbuff ) Employee; //undefined behavior
However, char arrays of automatic storage type are not guaranteed to meet the necessary alignment requirements of
objects of other types. Therefore, constructing an object of a preallocated buffer of automatic storage type can result
in undefined behavior. Furthermore, creating a new object at a storage location that was previously occupied by a
const object with static or automatic storage type also results in undefined behavior. For example
const Employee emp;
void bad_placement() //attempting to construct a new object
//at the storage location of a const object
{
emp.Employee::~Employee();
new (&emp) const Employee; // undefined behavior
}
Member Alignment
The size of a class or a struct might be larger than the result of adding the size of each data member in it. This is
because the compiler is allowed to add additional padding bytes between members whose size does not fit exactly into
a machine word (see also Chapter 13). For example
#include <cstring>
using namespace std;
struct Person
{
char firstName[5];
int age; // int occupies 4 bytes
char lastName[8];
}; //the actual size of Person is most likely larger than 17 bytes
void func()
{
Person person = {{"john"}, 30, {"lippman"}};
memset(&person, 0, 5+4+8 ); //may not erase the contents of
//person properly
}
On a 32-bit architecture, three additional bytes can be inserted between the first and the second members of Person,
increasing the size of Person from 17 bytes to 20.
On some implementations, the memset() call does not clear the last three bytes of the member lastName.
Therefore, use the sizeof operator to calculate the correct size:
memset(&p, 0, sizeof(Person));
ANSI/ISO C++ Professional Programmer's Handbook - Chapter 11 - Memmory Management
file:///D|/Cool Stuff/old/ftp/1/1/ch11/ch11.htm (12 von 23) [12.05.2000 14:46:34]
The Size Of A Complete Object Can Never Be Zero
An empty class doesn't have any data members or member functions. Therefore, the size of an instance is seemingly
zero. However, C++ guarantees that the size of a complete object is never zero. Consider the following example:
class Empty {};
Empty e; // e occupies at least 1 byte of memory
If an object is allowed to occupy zero bytes of storage, its address can overlap with the address of a different object.
The most obvious case is an array of empty objects whose elements all have an identical address. To guarantee that a
complete object always has a distinct memory address, a complete object occupies at least one byte of memory.
Non-complete objects -- for example, base class subobjects in a derived class -- can occupy zero bytes of memory.
User-Defined Versions of new and delete Cannot Be
Declared in a Namespace
User-defined versions of new and delete can be declared in a class scope. However, it is illegal to declare them in
a namespace. To see why, consider the following example:
char *pc;
namespace A
{
void* operator new ( size_t );
void operator delete ( void * );
void func ()
{
pc = new char ( 'a');
}
}
void f() { delete pc; } // A::delete or ::delete?
Declaring new and delete in namespace A is confusing for both compilers and human readers. Some programmers
might expect the operator A::delete to be selected in the function f() because it matches the operator new that
was used to allocate the storage. In contrast, others might expect delete to be called because A::delete is not
visible in f(). For this reason, the Standardization committee decided to disallow declarations of new and delete
in a namespace.
Overloading new and delete in a Class
It is possible to override new and delete and define a specialized form for them for a given class. Thus, for a class
C that defines these operators, the following statements
C* p = new C;
delete p;
invoke the class's versions of new and delete, respectively. Defining class-specific versions of new and delete
is useful when the default memory management scheme is unsuitable. This technique is also used in applications that
have a custom memory pool. In the following example, operator new for class C is redefined to alter the default
behavior in case of an allocation failure; instead of throwing std::bad_alloc, this specific version throws a
ANSI/ISO C++ Professional Programmer's Handbook - Chapter 11 - Memmory Management
file:///D|/Cool Stuff/old/ftp/1/1/ch11/ch11.htm (13 von 23) [12.05.2000 14:46:34]