Переопределение функции свободной памяти в C - PullRequest
0 голосов
/ 12 января 2011

Я переопределяю функции памяти в C, и мне интересно, может ли эта идея работать в качестве реализации для функции free ():

    typedef struct _mem_dictionary
    {
        void *addr;
        size_t size;
    } mem_dictionary;

    mem_dictionary *dictionary = NULL; //array of memory dictionaries
    int dictionary_ct = 0;         //dictionary struct counter

void *malloc(size_t size)
   {
    void *return_ptr = (void *) sbrk(size); 

    if (dictionary == NULL) 
        dictionary = (void *) sbrk(1024 * sizeof(mem_dictionary));  




    dictionary[dictionary_ct].addr = return_ptr; 
    dictionary[dictionary_ct].size = size;      
    dictionary_ct++;                 
    printf("malloc(): %p assigned memory\n",return_ptr); 
    return return_ptr;               

    }

    void free(void *ptr)
    {


    size_t i;
    int flag = 0;

     for(i = 0; i < dictionary_ct ; i++){

        if(dictionary[i].addr == ptr){
            dictionary[i].addr=NULL;
            dictionary[i].size = 0;
            flag = 1;
            break;
            }
        }

        if(!flag){
            printf("Remember to free!\n");
        }


    }

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 12 января 2011

Нет, не будет. Адрес, который вы «освобождаете», фактически теряется после такого звонка. Как вы узнаете, что конкретный кусок памяти снова доступен для выделения?

Было проведено много исследований в этой области, вот краткий обзор - Быстрое выделение памяти в Dr. Dobbs.

Редактировать 0:

Вы ошибаетесь в отношении sbrk(2) - это не «лучший malloc», и вы не можете использовать его как таковой. Этот системный вызов изменяет конец сегмента данных процесса .

0 голосов
/ 12 января 2011

Мало вещей:

  1. Где вы выделяете память для dictionary?
  2. Как вы распределяете память, на которую указывает dictionary->addr? Без кода для malloc не будет видно, будет ли работать free.
  3. Если в вашей функции malloc вы не просматриваете каждый адрес памяти, доступный процессу, чтобы проверить, не используется ли он вашим dictionary, простое назначение dictionary[i].addr=NULL не "освободит" память и определенно не хранить его для повторного использования.

Кстати, функция printf в вашей версии free будет печатать Remember to free!, когда пользователь бесплатно вызывает указатель, который предположительно не выделен, верно? Тогда почему "не забудьте освободить"?

Изменить:

Так что с этой функцией malloc нет, ваш free не освобождает память. Прежде всего, вы теряете адрес памяти, поэтому каждый раз, когда вы называете это malloc, вы фактически продвигаете процесс прерывания немного дальше и никогда не используете повторно освобожденные области памяти. Один из способов решения этой проблемы состоит в том, чтобы как-то отслеживать местоположения, которые вы «освободили», чтобы в следующий раз, когда вызывается malloc, вы могли проверить, достаточно ли у вас памяти, уже выделено процессу, и затем повторно использовать эти местоположения. Кроме того, помните, что sbrk является оберткой вокруг brk, который является дорогим системным вызовом, вы должны оптимизировать свой malloc так, чтобы большая часть памяти запрашивалась из ОС с использованием sbrk, а затем просто отслеживать, какие часть, которую вы используете, и какая часть доступна.

...