官术网_书友最值得收藏!

The heap

We described the stack as a manager of variables with automatic storage duration. The word automatic suggests that programmers shouldn't care about the actual memory allocation and deallocation. Automatic storage duration could be achieved only if the size of data or a collection of the data is known beforehand. This way, the compiler is aware of the number and type of function arguments and local variables. At this point, it seems more than fine, but programs tend to work with dynamic data— data of an unknown size. We will study dynamic memory management in detail in Chapter 5, Memory Management and Smart Pointers; for now, let's look at a simplified diagram of memory segments and find out what the heap is used for:

The program uses the heap segment in order to request more memory space than has been required before. This is done at runtime, which means the memory is being allocated dynamically during the program execution. The program requests the OS for new memory space whenever required. The OS doesn't actually know whether the memory is required for an integer, or for a user-defined Point, or even for an array of user-defined Point. The program requests the memory by passing the actual size of bytes that it requires. For example, to request a space for an object of type Point, the malloc() function can be used as follows:

#include <cstdlib>
struct Point {
float x;
float y;
};

int main() {
std::malloc(sizeof(Point));
}
The malloc() function came from the C language and to use it we need to include the <cstdlib> header file.

The malloc() function allocates a contiguous memory space of sizeof(Point) bytes— let's say 8 bytes. It then returns the address of the first byte of that memory as it is the only way to provide access to space. And the thing is, malloc() doesn't actually know whether we requested memory space for a Point object or an int, and it simply returns  void*. void* stores the address of the first byte of allocated memory, but it definitely cannot be used to fetch the actual data by dereferencing the pointer simply because void does not define the size of the data. Take a look at the following diagram; it shows that malloc allocates memory on the heap:

To actually use the memory space, we need to cast the void pointer to the desired type:

void* raw = std::malloc(sizeof(Point));
Point* p = static_cast<Point*>(raw);

Or, simply declare and initialize the pointer with a cast result:

Point* p = static_cast<Point*>(std::malloc(sizeof(Point)));

C++ solves this headache by introducing the new operator, which automatically fetches the size of the memory space to be allocated and converts the result to the desired type:

Point* p = new Point;

Dynamic memory management is a manual process; there is no similar construct to the stack that automatically deallocates the memory space if it is not required anymore. To manage the memory resource correctly, we should use the delete operator when we want to deallocate the space. We will find out the details in Chapter 5 Memory Management and Smart Pointers.

What happens when we access the members of the Point object pointed to by p? Dereferencing p returns the full Point object, so to change the value of member x, we should do the following:

(*p).x = 0.24;

Or, better still, access it with the arrow operator:

p->x = 0.24;

We will dive into the user-defined types and structs in particular in Chapter 3, Details of Object-Oriented Programming.

主站蜘蛛池模板: 双江| 陕西省| 湾仔区| 昂仁县| 阿城市| 隆回县| 崇州市| 云浮市| 巴彦县| 连云港市| 隆化县| 历史| 永宁县| 湖南省| 集安市| 墨竹工卡县| 鸡西市| 石林| 凌云县| 林口县| 离岛区| 定远县| 习水县| 论坛| 新巴尔虎左旗| 黄浦区| 万盛区| 石嘴山市| 闽侯县| 叙永县| 绥江县| 哈巴河县| 遂昌县| 古丈县| 甘德县| 鄂伦春自治旗| 霞浦县| 仁寿县| 白河县| 五寨县| 湖南省|