Pregunta

Tengo un bloque de código que parece ser el código detrás malloc. Pero mientras paso por el código, me da la sensación de que partes del código están desaparecidos. ¿Alguien sabe si hay una parte de la función que le falta? No siempre se combinan malloc trozos adyacentes juntos?

int heap[10000];
void* malloc(int size) {
int sz = (size + 3) / 4;
int chunk = 0;
if(heap[chunk] > sz) {
    int my_size = heap[chunk];
    if (my_size < 0) {
      my_size = -my_size
    }
    chunk = chunk + my_size + 2;
    if (chunk == heap_size) { 
      return 0;
    }
}
¿Fue útil?

Solución

El código detrás de malloc es ciertamente mucho más complejo que eso. Hay varias estrategias. Un código popular es el href="http://g.oswego.edu/dl/html/malloc.html" rel="noreferrer"> dlmalloc biblioteca . A uno más simple se describe en K & R.

Otros consejos

El código es obviamente incompleta (no todos los caminos devuelven un valor). Pero en cualquier caso esto no es un malloc "real". Esto es probablemente un intento de aplicar un "modelo" muy simplificado de 'malloc'. El enfoque elegido por el autor del código no puede realmente conducir a una aplicación práctica y útil.

(Y por cierto, estándar 'parámetro de malloc tiene tipo 'size_t', no 'int').

Bueno, un error en el código es que no devuelve un puntero a los datos.

sospecho que el mejor enfoque para que el código está [eliminar].

Cuando sea posible, espero que malloc intentará poner diferentes peticiones cerca uno del otro, ya que tendrá un bloque de código que está disponible para malloc, hasta que se tiene que conseguir un nuevo bloque.

Sin embargo, eso también depende de las exigencias impuestas por la arquitectura del sistema operativo y hardware. Si sólo se le permite solicitar una cierta cantidad mínima de código, entonces puede ser que cada asignación no estará cerca unos de otros.

Como otros han mencionado, hay problemas con el fragmento de código.

Puede encontrar diversos proyectos de código abierto que tienen su propia función malloc, y que puede ser mejor para mirar a uno de ellos, con el fin de tener una idea de lo que falta.

malloc es de asignada dinámicamente memoria. Y esto implica sbrk, mmap, o tal vez algunas otras funciones del sistema para Windows y / o otras arquitecturas. No estoy seguro de lo que su int heap[10000] es porque, como el código es demasiado incompleta.

La versión de EFFO hacer un poco más sentido, pero luego se introduce otro negro get_block función de la caja, por lo que no ayuda mucho.

El código parece ser dirigido en una máquina de metal, normalmente de correlación de direcciones no virtual en un sistema tal que sólo utilizan espacio de direcciones físicas directamente.

Ver mi entendimiento, en un sistema de 32 bits, sizeof (ptr) = 4 bytes:

extern block_t *block_head; // the real heap, and its address 
                            // is >= 0x80000000, see below "my_size < 0"
extern void *get_block(int index); // get a block from the heap 
                                   // (lead by block_head)
int heap[10000]; // just the indicators, not the real heap

void* malloc(int size) 
{
    int sz = (size + 3) / 4; // make the size aligns with 4 bytes,
                             // you know, allocated size would be aligned.
    int chunk = 0; // the first check point
    if(heap[chunk] > sz) { // the value is either a valid free-block size 
                           // which meets my requirement, or an 
                           // address of an allocated block
        int my_size = heap[chunk]; // verify size or address
        if (my_size < 0) { // it is an address, say a 32-bit value which 
                           // is >0x8000...., not a size. 
              my_size = -my_size // the algo, convert it
        }
        chunk = chunk + my_size + 2; // the algo too, get available 
                                     // block index
        if (chunk == heap_size) { // no free chunks left
           return NULL; // Out of Memory
        }
        void *block = get_block(chunk);
        heap[chunk] = (int)block;
        return block;
    }
    // my blocks is too small initially, none of the blocks 
    // will meet the requirement
    return NULL;
}

EDIT: ¿Podría alguien ayuda a explicar el algo, es decir, la conversión de direcciones -> my_size -> trozo? ya sabes, cuando recuperación de llamada, decir libre (* addr void), que va a utilizar esta dirección -> my_size -.> trozo algo también, para actualizar el montón [fragmento] consecuencia después de devolver el bloque para el montón

Para pequeña para ser una implementación de malloc toda

Tome una mirada en las fuentes de la biblioteca C de Visual Studio 6.0, allí se encuentra la implementación de malloc si recuerdo correctamente

scroll top