-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcustom-allocators.html
More file actions
415 lines (365 loc) · 23.1 KB
/
Copy pathcustom-allocators.html
File metadata and controls
415 lines (365 loc) · 23.1 KB
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<title>Asignadores de Memoria Personalizados</title>
<link rel="stylesheet" type="text/css" href="rustbook.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<div id="nav">
<button id="toggle-nav">
<span class="sr-only">Toggle navigation</span>
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</button>
</div>
<div id='toc' class='mobile-hidden'>
<ul class='chapter'>
<li><a href='README.html'><b>1.</b> Introduction</a>
</li>
<li><a href='getting-started.html'><b>2.</b> Primeros Pasos</a>
<ul class='section'>
<li><a href='installing-rust.html'><b>2.1.</b> Instalando Rust</a>
</li>
<li><a href='hello-world.html'><b>2.2.</b> ¡Hola, mundo!</a>
</li>
<li><a href='hello-cargo.html'><b>2.3.</b> ¡Hola, Cargo!</a>
</li>
</ul>
</li>
<li><a href='learn-rust.html'><b>3.</b> Aprende Rust</a>
<ul class='section'>
<li><a href='guessing-game.html'><b>3.1.</b> El Juego de las Adivinanzas</a>
</li>
<li><a href='dining-philosophers.html'><b>3.2.</b> La Cena de los Filósofos</a>
</li>
<li><a href='rust-inside-other-languages.html'><b>3.3.</b> Rust dentro de otros Lenguajes</a>
</li>
</ul>
</li>
<li><a href='effective-rust.html'><b>4.</b> Rust Efectivo</a>
<ul class='section'>
<li><a href='the-stack-and-the-heap.html'><b>4.1.</b> La Pila y el Montículo</a>
</li>
<li><a href='testing.html'><b>4.2.</b> Pruebas</a>
</li>
<li><a href='conditional-compilation.html'><b>4.3.</b> Compilación Condicional</a>
</li>
<li><a href='documentation.html'><b>4.4.</b> Documentación</a>
</li>
<li><a href='iterators.html'><b>4.5.</b> Iteradores</a>
</li>
<li><a href='concurrency.html'><b>4.6.</b> Concurrencia</a>
</li>
<li><a href='error-handling.html'><b>4.7.</b> Manejo de Errores</a>
</li>
<li><a href='ffi.html'><b>4.8.</b> FFI</a>
</li>
<li><a href='borrow-and-asref.html'><b>4.9.</b> Borrow y AsRef</a>
</li>
<li><a href='release-channels.html'><b>4.10.</b> Canales de Distribución</a>
</li>
</ul>
</li>
<li><a href='syntax-and-semantics.html'><b>5.</b> Sintaxis y Semantica</a>
<ul class='section'>
<li><a href='variable-bindings.html'><b>5.1.</b> Enlaces a Variables</a>
</li>
<li><a href='functions.html'><b>5.2.</b> Funciones</a>
</li>
<li><a href='primitive-types.html'><b>5.3.</b> Tipos Primitivos</a>
</li>
<li><a href='comments.html'><b>5.4.</b> Comentarios</a>
</li>
<li><a href='if.html'><b>5.5.</b> if</a>
</li>
<li><a href='loops.html'><b>5.6.</b> Ciclos</a>
</li>
<li><a href='ownership.html'><b>5.7.</b> Pertenencia</a>
</li>
<li><a href='references-and-borrowing.html'><b>5.8.</b> Referencias y Préstamo</a>
</li>
<li><a href='lifetimes.html'><b>5.9.</b> Tiempos de Vida</a>
</li>
<li><a href='mutability.html'><b>5.10.</b> Mutabilidad</a>
</li>
<li><a href='structs.html'><b>5.11.</b> Estructuras</a>
</li>
<li><a href='enums.html'><b>5.12.</b> Enumeraciones</a>
</li>
<li><a href='match.html'><b>5.13.</b> Match</a>
</li>
<li><a href='patterns.html'><b>5.14.</b> Patrones</a>
</li>
<li><a href='method-syntax.html'><b>5.15.</b> Sintaxis de Métodos</a>
</li>
<li><a href='vectors.html'><b>5.16.</b> Vectores</a>
</li>
<li><a href='strings.html'><b>5.17.</b> Cadenas de Caracteres</a>
</li>
<li><a href='generics.html'><b>5.18.</b> Genéricos</a>
</li>
<li><a href='traits.html'><b>5.19.</b> Traits</a>
</li>
<li><a href='drop.html'><b>5.20.</b> Drop</a>
</li>
<li><a href='if-let.html'><b>5.21.</b> if let</a>
</li>
<li><a href='trait-objects.html'><b>5.22.</b> Objetos Trait</a>
</li>
<li><a href='closures.html'><b>5.23.</b> Closures</a>
</li>
<li><a href='ufcs.html'><b>5.24.</b> Sintaxis Universal de Llamada a Funciones</a>
</li>
<li><a href='crates-and-modules.html'><b>5.25.</b> Crates y Módulos</a>
</li>
<li><a href='const-and-static.html'><b>5.26.</b> `const` y `static`</a>
</li>
<li><a href='attributes.html'><b>5.27.</b> Atributos</a>
</li>
<li><a href='type-aliases.html'><b>5.28.</b> Alias `type`</a>
</li>
<li><a href='casting-between-types.html'><b>5.29.</b> Conversión entre Tipos</a>
</li>
<li><a href='associated-types.html'><b>5.30.</b> Tipos Asociados</a>
</li>
<li><a href='unsized-types.html'><b>5.31.</b> Tipos sin Tamaño</a>
</li>
<li><a href='operators-and-overloading.html'><b>5.32.</b> Operadores y Sobrecarga</a>
</li>
<li><a href='deref-coercions.html'><b>5.33.</b> Coerciones Deref</a>
</li>
<li><a href='macros.html'><b>5.34.</b> Macros</a>
</li>
<li><a href='raw-pointers.html'><b>5.35.</b> Apuntadores Planos</a>
</li>
<li><a href='unsafe.html'><b>5.36.</b> `unsafe`</a>
</li>
</ul>
</li>
<li><a href='nightly-rust.html'><b>6.</b> Rust Nocturno</a>
<ul class='section'>
<li><a href='compiler-plugins.html'><b>6.1.</b> Plugins del Compilador</a>
</li>
<li><a href='inline-assembly.html'><b>6.2.</b> Ensamblador en Linea</a>
</li>
<li><a href='no-stdlib.html'><b>6.3.</b> No stdlib</a>
</li>
<li><a href='intrinsics.html'><b>6.4.</b> Intrínsecos</a>
</li>
<li><a href='lang-items.html'><b>6.5.</b> Items de Lenguaje</a>
</li>
<li><a href='advanced-linking.html'><b>6.6.</b> Enlace Avanzado</a>
</li>
<li><a href='benchmark-tests.html'><b>6.7.</b> Pruebas de Rendimiento</a>
</li>
<li><a href='box-syntax-and-patterns.html'><b>6.8.</b> Sintaxis Box y Patrones</a>
</li>
<li><a href='slice-patterns.html'><b>6.9.</b> Patrones Slice</a>
</li>
<li><a href='associated-constants.html'><b>6.10.</b> Constantes Asociadas</a>
</li>
<li><a class='active' href='custom-allocators.html'><b>6.11.</b> Asignadores de Memoria Personalizados</a>
</li>
</ul>
</li>
<li><a href='glossary.html'><b>7.</b> Glosario</a>
</li>
<li><a href='bibliography.html'><b>8.</b> Bibliografia</a>
</li>
</ul>
</div>
<div id='page-wrapper'>
<div id='page'>
<h1 class="title">Asignadores de Memoria Personalizados</h1>
<p>La asignación de memoria no es siempre la cosa mas fácil de hacer, y si bien Rust generalmente lo hace por defecto en algunas oportunidades se hace necesario personalizar como ocurre la asignación de memoria. El compilador y la biblioteca estándar actualmente permiten cambiar el asignador global de memoria por defecto a usar en tiempo de compilación. El diseño esta actualmente delineado en el <a href="https://github.com/rust-lang/rfcs/blob/master/text/1183-swap-out-jemalloc.md">RFC 1183</a> pero esta sección te dará un tour acerca de como poner tu asignador de memoria personalizado en funcionamiento.</p>
<h1 id='asignador-por-defecto' class='section-header'><a href='#asignador-por-defecto'>Asignador por defecto</a></h1>
<p>El compilador actualmente viene con dos asignadores de memoria por defecto: <code>alloc_system</code> y <code>alloc_jemalloc</code> (algunos sistemas, sin embargo, no soportan jemalloc). Dichos asignadores son crates regulares Rust y contienen la implementación para la asignación y liberación de memoria. La biblioteca estándar no es compilada asumiendo ningún asignador en particular, y el compilador decidirá cual asignador esta en uso en tiempo de compilación dependiendo del tipo de artefacto de salida que este siendo producido.</p>
<p>Los ejecutables generados por el compilador usaran <code>alloc_jemalloc</code> por defecto (donde este disponible). En esta situación el compilador "controla el mundo" en el sentido que posee poder acerca del enlace final. Esto principalmente significa que la decisión de cual asignador es usado puede ser delegada al compilador.</p>
<p>Las bibliotecas estáticas y dinámicas, sin embargo, harán uso de el asignador <code>alloc_system</code> por defecto. En esta situación Rust es típicamente un 'invitado' dentro de otra aplicación u otro mundo en el cual no puede de manera autoritaria decidir cual asignador de memoria usar. Como resultado recurre a las APIs estándar (e.j. <code>malloc</code> y <code>free</code>) para adquirir y liberar memoria.</p>
<h1 id='cambiando-asignadores' class='section-header'><a href='#cambiando-asignadores'>Cambiando Asignadores</a></h1>
<p>Si bien las elecciones del compilador pueden funcionar la mayoría del tiempo, algunas veces es necesario personalizar ciertos aspectos. Sobreescribir la decisión acerca de cual asignador se debe usar puede hacerse simplemente enlazando con el asignador deseado:</p>
<span class='rusttest'>#![feature(alloc_system)]
extern crate alloc_system;
fn main() {
let a = Box::new(4); // asigna desde el asignador de memoria del sistema
println!("{}", a);
}
</span><pre class='rust rust-example-rendered'>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>feature</span>(<span class='ident'>alloc_system</span>)]</span>
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>alloc_system</span>;
<span class='kw'>fn</span> <span class='ident'>main</span>() {
<span class='kw'>let</span> <span class='ident'>a</span> <span class='op'>=</span> <span class='ident'>Box</span>::<span class='ident'>new</span>(<span class='number'>4</span>); <span class='comment'>// asigna desde el asignador de memoria del sistema</span>
<span class='macro'>println</span><span class='macro'>!</span>(<span class='string'>"{}"</span>, <span class='ident'>a</span>);
}</pre>
<p>En este ejemplo el ejecutable generado no enlazara con jemalloc por defecto y en su lugar usara el asignador del sistema. De manera similar, para generar una biblioteca dinámica que use jemalloc por defecto uno podría escribir:</p>
<span class='rusttest'>#![feature(alloc_jemalloc)]
#![crate_type = "dylib"]
extern crate alloc_jemalloc;
pub fn foo() {
let a = Box::new(4); // asigna desde jemalloc
println!("{}", a);
}
fn main() {}
</span><pre class='rust rust-example-rendered'>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>feature</span>(<span class='ident'>alloc_jemalloc</span>)]</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>crate_type</span> <span class='op'>=</span> <span class='string'>"dylib"</span>]</span>
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>alloc_jemalloc</span>;
<span class='kw'>pub</span> <span class='kw'>fn</span> <span class='ident'>foo</span>() {
<span class='kw'>let</span> <span class='ident'>a</span> <span class='op'>=</span> <span class='ident'>Box</span>::<span class='ident'>new</span>(<span class='number'>4</span>); <span class='comment'>// asigna desde jemalloc</span>
<span class='macro'>println</span><span class='macro'>!</span>(<span class='string'>"{}"</span>, <span class='ident'>a</span>);
}</pre>
<h1 id='escribiendo-un-asignador-personalizado' class='section-header'><a href='#escribiendo-un-asignador-personalizado'>Escribiendo un asignador personalizado</a></h1>
<p>Algunas veces las opciones de jemalloc vs el asignador del sistema no son suficientes y un asignador completamente nuevo se hace necesario. En este caso escribirías tu propio crate implementando el API de asignación de memoria. (e.j lo mismo que <code>alloc_system</code> o <code>alloc_jemalloc</code>). Como ejemplo, echemos un vistazo a una version simplificada y anotada de <code>alloc_system</code></p>
<span class='rusttest'>// necesario solo para rustdoc --test
#![feature(lang_items)]
// El compilador necesita ser instruido acerca del hecho que este crate es un
// asignador para que entienda que cuando se enlace con el no se debe enlazar
// con otro asignador como jemalloc
#![feature(allocator)]
#![allocator]
// Los asignadores de memoria no tienen permitido depender de la biblioteca
// estándar que a su vez requiere un asignador con la finalidad de evitar
// dependencias cíclicas. Este crate, sin embargo, puede hacer uso de todo
// en libcore.
#![no_std]
// Démosle un nombre a nuestro asignador personalizado
#![crate_name = "my_allocator"]
#![crate_type = "rlib"]
// Nuestro asignador de sistema hará uso de el crate libc que vive en el árbol
// de Rust. Nota que actualmente el crate libc externo (crates.io) no puede ser
// usado debido a que este enlaza con la biblioteca estándar (e.j. `#![no_std]`
// no esta estable todavía). Es por ello que requiere específicamente la
// version en el arbol.
#![feature(libc)]
extern crate libc;
// A continuación se listan las cinco funciones de asignación requeridas
// actualmente por los asignadores de memoria. Los tipos en sus firmas y
// nombres de símbolo actualmente no son chequeados por el compilador,
// pero esta es una extension futura y son requeridas para coincidir con
// lo que sigue a continuación.
//
// Nota que las funciones `malloc` y `realloc` estándar no proveen una
// via para comunicar la alineación y es por ello que esta implementación
// necesitaría ser mejorada en lo que respecta a la alineación.
#[no_mangle]
pub extern fn __rust_allocate(size: usize, _align: usize) -> *mut u8 {
unsafe { libc::malloc(size as libc::size_t) as *mut u8 }
}
#[no_mangle]
pub extern fn __rust_deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
unsafe { libc::free(ptr as *mut libc::c_void) }
}
#[no_mangle]
pub extern fn __rust_reallocate(ptr: *mut u8, _old_size: usize, size: usize,
_align: usize) -> *mut u8 {
unsafe {
libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
}
}
#[no_mangle]
pub extern fn __rust_reallocate_inplace(_ptr: *mut u8, old_size: usize,
_size: usize, _align: usize) -> usize {
old_size // this api is not supported by libc
}
#[no_mangle]
pub extern fn __rust_usable_size(size: usize, _align: usize) -> usize {
size
}
// necesario solo para hacer que rustdoc corra las pruebas
fn main() {}
#[lang = "panic_fmt"] fn panic_fmt() {}
#[lang = "eh_personality"] fn eh_personality() {}
#[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {}
#[no_mangle] pub extern fn rust_eh_register_frames () {}
#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
</span><pre class='rust rust-example-rendered'>
<span class='comment'>// El compilador necesita ser instruido acerca del hecho que este crate es un</span>
<span class='comment'>// asignador para que entienda que cuando se enlace con el no se debe enlazar</span>
<span class='comment'>// con otro asignador como jemalloc</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>feature</span>(<span class='ident'>allocator</span>)]</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>allocator</span>]</span>
<span class='comment'>// Los asignadores de memoria no tienen permitido depender de la biblioteca</span>
<span class='comment'>// estándar que a su vez requiere un asignador con la finalidad de evitar</span>
<span class='comment'>// dependencias cíclicas. Este crate, sin embargo, puede hacer uso de todo</span>
<span class='comment'>// en libcore.</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>no_std</span>]</span>
<span class='comment'>// Démosle un nombre a nuestro asignador personalizado</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>crate_name</span> <span class='op'>=</span> <span class='string'>"my_allocator"</span>]</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>crate_type</span> <span class='op'>=</span> <span class='string'>"rlib"</span>]</span>
<span class='comment'>// Nuestro asignador de sistema hará uso de el crate libc que vive en el árbol</span>
<span class='comment'>// de Rust. Nota que actualmente el crate libc externo (crates.io) no puede ser</span>
<span class='comment'>// usado debido a que este enlaza con la biblioteca estándar (e.j. `#![no_std]`</span>
<span class='comment'>// no esta estable todavía). Es por ello que requiere específicamente la </span>
<span class='comment'>// version en el arbol.</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>feature</span>(<span class='ident'>libc</span>)]</span>
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>libc</span>;
<span class='comment'>// A continuación se listan las cinco funciones de asignación requeridas</span>
<span class='comment'>// actualmente por los asignadores de memoria. Los tipos en sus firmas y</span>
<span class='comment'>// nombres de símbolo actualmente no son chequeados por el compilador,</span>
<span class='comment'>// pero esta es una extension futura y son requeridas para coincidir con</span>
<span class='comment'>// lo que sigue a continuación.</span>
<span class='comment'>//</span>
<span class='comment'>// Nota que las funciones `malloc` y `realloc` estándar no proveen una</span>
<span class='comment'>// via para comunicar la alineación y es por ello que esta implementación</span>
<span class='comment'>// necesitaría ser mejorada en lo que respecta a la alineación.</span>
<span class='attribute'>#[<span class='ident'>no_mangle</span>]</span>
<span class='kw'>pub</span> <span class='kw'>extern</span> <span class='kw'>fn</span> <span class='ident'>__rust_allocate</span>(<span class='ident'>size</span>: <span class='ident'>usize</span>, <span class='ident'>_align</span>: <span class='ident'>usize</span>) <span class='op'>-></span> <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>u8</span> {
<span class='kw'>unsafe</span> { <span class='ident'>libc</span>::<span class='ident'>malloc</span>(<span class='ident'>size</span> <span class='kw'>as</span> <span class='ident'>libc</span>::<span class='ident'>size_t</span>) <span class='kw'>as</span> <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>u8</span> }
}
<span class='attribute'>#[<span class='ident'>no_mangle</span>]</span>
<span class='kw'>pub</span> <span class='kw'>extern</span> <span class='kw'>fn</span> <span class='ident'>__rust_deallocate</span>(<span class='ident'>ptr</span>: <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>u8</span>, <span class='ident'>_old_size</span>: <span class='ident'>usize</span>, <span class='ident'>_align</span>: <span class='ident'>usize</span>) {
<span class='kw'>unsafe</span> { <span class='ident'>libc</span>::<span class='ident'>free</span>(<span class='ident'>ptr</span> <span class='kw'>as</span> <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>libc</span>::<span class='ident'>c_void</span>) }
}
<span class='attribute'>#[<span class='ident'>no_mangle</span>]</span>
<span class='kw'>pub</span> <span class='kw'>extern</span> <span class='kw'>fn</span> <span class='ident'>__rust_reallocate</span>(<span class='ident'>ptr</span>: <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>u8</span>, <span class='ident'>_old_size</span>: <span class='ident'>usize</span>, <span class='ident'>size</span>: <span class='ident'>usize</span>,
<span class='ident'>_align</span>: <span class='ident'>usize</span>) <span class='op'>-></span> <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>u8</span> {
<span class='kw'>unsafe</span> {
<span class='ident'>libc</span>::<span class='ident'>realloc</span>(<span class='ident'>ptr</span> <span class='kw'>as</span> <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>libc</span>::<span class='ident'>c_void</span>, <span class='ident'>size</span> <span class='kw'>as</span> <span class='ident'>libc</span>::<span class='ident'>size_t</span>) <span class='kw'>as</span> <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>u8</span>
}
}
<span class='attribute'>#[<span class='ident'>no_mangle</span>]</span>
<span class='kw'>pub</span> <span class='kw'>extern</span> <span class='kw'>fn</span> <span class='ident'>__rust_reallocate_inplace</span>(<span class='ident'>_ptr</span>: <span class='op'>*</span><span class='kw-2'>mut</span> <span class='ident'>u8</span>, <span class='ident'>old_size</span>: <span class='ident'>usize</span>,
<span class='ident'>_size</span>: <span class='ident'>usize</span>, <span class='ident'>_align</span>: <span class='ident'>usize</span>) <span class='op'>-></span> <span class='ident'>usize</span> {
<span class='ident'>old_size</span> <span class='comment'>// this api is not supported by libc</span>
}
<span class='attribute'>#[<span class='ident'>no_mangle</span>]</span>
<span class='kw'>pub</span> <span class='kw'>extern</span> <span class='kw'>fn</span> <span class='ident'>__rust_usable_size</span>(<span class='ident'>size</span>: <span class='ident'>usize</span>, <span class='ident'>_align</span>: <span class='ident'>usize</span>) <span class='op'>-></span> <span class='ident'>usize</span> {
<span class='ident'>size</span>
}
</pre>
<p>Despues que compilamos este crate, puede ser usado como sigue:</p>
<span class='rusttest'>extern crate my_allocator;
fn main() {
let a = Box::new(8); // asigna memoria via nuestro asignador
println!("{}", a);
}
</span><pre class='rust rust-example-rendered'>
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>my_allocator</span>;
<span class='kw'>fn</span> <span class='ident'>main</span>() {
<span class='kw'>let</span> <span class='ident'>a</span> <span class='op'>=</span> <span class='ident'>Box</span>::<span class='ident'>new</span>(<span class='number'>8</span>); <span class='comment'>// asigna memoria via nuestro asignador</span>
<span class='macro'>println</span><span class='macro'>!</span>(<span class='string'>"{}"</span>, <span class='ident'>a</span>);
}</pre>
<h1 id='limitaciones-de-los-asignadores-personalizados' class='section-header'><a href='#limitaciones-de-los-asignadores-personalizados'>Limitaciones de los asignadores personalizados</a></h1>
<p>Hay algunas restricciones cuando se trabaja con asignadores de memoria personalizados que pueden causar errores de compilación:</p>
<ul>
<li><p>Cualquier artefacto puede ser enlazado con un máximo de un asignador. Los ejecutables, dylibs y staticlibs deben ser enlazados con exactamente un asignador, de no haber sido seleccionado uno de manera explicita el compilador seleccionara uno. Por otro lado rlibs no necesitan enlazar con un asignador (pero igual pueden hacerlo).</p></li>
<li><p>Un consumidor de un asignador se etiqueta con <code>#![needs_allocator]</code> (e.j. el crate <code>liballoc</code> actualmente) y un crate <code>#[allocator]</code> no puede depender transitivamente en un crate que necesita un asignador (e.j las dependencias circulares no estan permitidas). Esto significa básicamente que los asignadores de memoria en la actualidad deben restringirse a libcore.</p></li>
</ul>
<script type="text/javascript">
window.playgroundUrl = "https://play.rust-lang.org";
</script>
<script src='rustbook.js'></script>
<script src='playpen.js'></script>
</div></div>
</body>
</html>