aboutsummaryrefslogtreecommitdiffstats
path: root/doc/info/chap/memory-allocation.texinfo
blob: b5b50944020ecd2a958cd2e2c3a6861262344bf5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
@node Memory allocation
@chapter Memory allocation

The ability to allocate memory of on at compile-time
unknown amount is an important feature for most
programs.

On modern operating systems, processes do not have
direct access to the memory. Only the operating system
kernel does. Instead, the process have virtual
memory address, that the kernel maps to either,
real @sc{RAM} memory, swap space (disc backed),
file segments, or zeroes.

Memory for a process is either allocated programmatically,
or when the process forks (is created) or exec:s
(changes process image.) The operating system kernel is
typically configured to share a much memory between processes
as possible. For example, and a process forks, they will
share their memory rather than duplicate the memory, and
the kernel will only remap the memory when the processs'
memory content diverges. It is also possible to allocate
memory in such a way that processes can share it. so that
updates from one process influences the other processes.

A process' virtual address space is divided into segments.
There are three important segments.

@table @i
@item text segment
When a process exec:s this segment is allocated.
It contains instructions, static constants, and
literals.
@item BSS segment
When a process exec:s this segment is allocated.
It contains all global and static variables that are
initialised to zero or lacks explicit initialisation.
On some systems this segment is merged into the data
segment.
@item data segment
When a process exec:s this segment is allocated.
It is filled all global and static variables that
are not covered by the @sc{BSS} segment.
This segment's lower end is fixed, and its upper end
is unfixed; it can be resized. Any part of the segment
that is a result of it being resized, is referred to
as the heap.
@item stack segment
This segment contains a@footnote{Program stack's can
created programmtically, hence `a' rather than `the'.}
program stack. A program stack contains information
required to return after a function call, and automatic
variables. Depending on the platform and the function
it may also contain arguments passed in function calls
and return values. It grows as the stack grows, but
it does not shrink as the stack shrinks.
@end table

The layout of the segments is machine dependent and
operating system. However, a common@footnote{Keeping
in mind this cannot be assumed practice, and that
it is in fact different between systems.} layout is
have the text segment (as other fixed segments) start
at 0, and end at some positive address. The text
segment is then followed by the @sc{BSS} segment, and
the data segment. The stack segment however, grows
from the highest address (@math{-1} on two's
complement-machines) downwards. The process cannot
allocate any more memory when the allocation would
require the data segment to be grown to such an
extent that it would overlap with the stack segment.

In C there are multiple ways to allocate memory.
@itemize @bullet{}
@item
Variables that are declared outside functions are
called global variables@footnote{Even if that are
declared with @code{static}. In this context,
@code{static} is only use to hide object from
other translation units.}. These are stored either
in the @sc{BSS} segment or in the data segment, depending
on their initialisation. Pointer are stored as
numerical values, and the content is stored in the
text segment. Arrays however are not stored, but
their content is. In the data segment (or in the
@sc{BSS} segment if the elements are zeroes.) These
allocations are known as @i{static allocations}.
@item
Variables that are declared inside functions, with
@code{static}, are stored just like global variables.
These are called static variables, and remain unchanged
between function calls, and only change in statements
other than the declaration statement. These allocations
are known as @i{static allocations}.
@item
Variables that are declared inside functions (these
are known as local variables), without @code{static},
but with @code{auto}, are called automatic variables.
These are stored in the stack segment, and are
deallocated when the function returns. Local variables
that are declared with neither @code{static},
@code{auto}, or @code{register} are often though of
as automatic; however, the compiler may choose to
add @code{register}. These allocations are known as
@i{automatic allocations}@footnote{Known in some other
programming languages as stack-allocations.}.
@item
Variables that are declared with @code{register}
are not stored in any segment. They lack addresses
and stored as CPU registers.
@item
Using system calls, a heap can be created, where
new allocations are stored. These are often allocated
with the function @code{malloc}, and are known as
@i{dynamic allocations}@footnote{Known in some other
programming languages as heap-allocations.}.
@end itemize

Some compilers, including @sc{GCC}, provide two
additional ways to allocate memory.
@table @asis
@item @i{Variable-length arrays}
A simple example of variable-length arrays, available
with some compilers, is
@example
void function(size_t n)
@{
  int array[n];
  /* ... */
@}
@end example
Variable-length arrays have a special property:
they may be deallocated before the function returns.
In fact, they are returned once the variable becomes
invisible, this causes the follow example to work
without every exhausting the memory.
@example
void function(size_t n)
@{
  for (;;)
    @{
      int array[n];
      /* ... */
    @}
@}
@end example

@item @code{alloca}
@code{alloca} is a special function that is implement
by the compiler. It increases the stack and returns
a pointer to the beginning of the new part of the stack.
It is similar to variable-length arrays, however the
allocation is not deallocated before the function returns.
This causes the follow example to eventually exhaust
the memory.
@example
void function(size_t n)
@{
  for (;;)
    @{
      int pointer* = alloca(n);
      /* ... */
    @}
@}
@end example
@end table

Both of these allocation-methods are both automatic
and dynamic.


@menu
* The alloca function::                       Dynamically allocate automatically freed memory.
* Basic memory allocation::                   Basic functions for dynamic memory allocation.
* Resizing memory allocations::               How to resize memory allocations.
* Efficient stack-based allocations::         Improving the performance using constrained allocation methods.
* Resizing the data segment::                 How to change the size of the heap.
* Memory locking::                            How to prevent pages from being swapped out.
@end menu



@node The alloca function
@section The @code{alloca} function

TODO



@node Basic memory allocation
@section Basic memory allocation

TODO



@node Resizing memory allocations
@section Resizing memory allocations

TODO



@node Efficient stack-based allocations
@section Efficient stack-based allocations

TODO



@node Resizing the data segment
@section Resizing the data segment

TODO



@node Memory locking
@section Memory locking

TODO