2015-05-03 2 views
-1

Я хочу использовать что-то вроде этого, чтобы выделить память:Использует макрос для распределения памяти плохо?

void* pointers = NULL; 
#define MALLOC(size) ({\ 
    void* ptr = malloc(size); 
    ARRAYAPPEND(pointers, ptr);\ 
}) 
#define FREE(ptr) ({\ 
    ARRAYREMOVEBYVALUE(pointers, ptr);\ 
    free(ptr);\ 
}) 
#define FREEALL() ({\ 
    FREEARRAY(pointers);\ 
}) 

ARRAYAPPEND добавит элемент в массив или создать массив с элементом в нем, когда он указывает на NULL

ARRAYREMOVEBYVALUE будет free() все элементы из массива, которые имеют соответствующее значение. Если все значения в массиве совпадают, он освободит весь массив, используя FREEARRAY(). С ARRAYREMOVEBYEXPRESSION такие вещи, как strcmp(value, ""), также будут работать. (Не то, что я должен был бы использовать)

ARRAYSIZE возвращает размер массива, или 0, если он указывает на NULL

FREEARRAY освободит все указатели в массиве, и освободить сам массив после этого , Если массив указывает на NULL, никаких действий не будет.

Конечно, я также поддержу realloc и calloc.

Это хороший способ выделить и освободить память, есть ли библиотека, которая имеет более безопасный способ сделать это (я создаю эти макросы с нуля), должен ли я free() каждый отдельный адрес памяти вручную, или я должен полагаться на использование небезопасной, но работающей автоматической очистки ОС? (В настоящее время поддержка только для Windows 8 полностью прекрасна, а Windows 8 - автоматическая очистка)? Моя цель состоит в том, чтобы освободить всю память о выходе из программы, и, очевидно, не во время выполнения

(я могу узнать себя, что

while (1) { 
    malloc(10000); 
} 

будет eventurely запустить из памяти, но мой вопрос, если это:

char* x = MALLOC(10000); 
FREEALL(); 

безопаснее, чем полагаться на ОС очистки, и если этого:

char* x = malloc(10000); 
free(x); 

предпочтителен выше используя макрос. Может быть, есть скрытые призывы к malloc, которые я не могу контролировать? В этих случаях нет никаких реальных оснований для использования макросов, но, например, для

while (strcmp(SUBSTRING(str, 0, 14), "Hello, world!") { 
    // Code (No cleanup) 
}) 

там могут быть скрыты вызовы malloc внутри SUBSTRING (например, для создания новой строки), который не будет free «d , Должен ли я использовать макросы в этом случае:

SESSION_SET("SESSION1"); 
while (strcmp(SUBSTRING(str, 0, 14), "Hello, world!") { 
    // Code (No cleanup) 
}) 
SESSION_FREE("SESSION1"); 

или будет полагаться на автоматическую очистку достаточно хорошо)

Моя проблема basicaly: Я хочу, чтобы выделить память без сохранения его адрес, я должен заставить себя сохранить каждый адрес и free() его вручную, следует ли использовать макрос, есть ли библиотека, которая делает это для меня, или я должен полагаться на очистку ОС?

Реакция на комментарий @wildplasser: Макрос - это встроенная функция ...: | (EDIT: Хорошо ... Может быть, макрос не проверяет типы, но это все.) Кроме того, я предпочитаю, чтобы набрать char* item = MALLOC(10);FREEALL(); выше набрав

void* array = NULL; // Array of pointers 
char* item = malloc(10); // Allocate item 
int size = (array == NULL ? 0 : sizeof(array)/sizeof(array[0])); // Get length of array 
array = realloc(array, (size + 1) * sizeof(item)); // Reallocate array 
array[size] = item; // Add item to new array 
size = (array == NULL ? 0 : sizeof(array)/sizeof(array[0])); // Get new size of array (Wow, a macro would be usefull, wouldn't it?) 
int i = 0; // Lets loop over all the items 
while (i < size) { // In our array of pointers 
    free(array[i]); // And free all those pointers 
} 
free(array); // Lets free the array too... 
array = NULL; // What did we end up doing? Nothing! 
+0

Никто в C не имеет автоматической очистки, кроме как через выход из процесса. Если вы хотите, чтобы все было очищено, когда вы покидаете область видимости, вам нужно либо использовать C++ с RAII, либо язык собранных мусором. – Mgetz

+0

Почему макросы, а не функции? –

+3

* Windows 8 имеет автоматическую очистку * У вас есть источник этого требования!?!? – Borgleader

ответ

1

Вся ваша работа здесь, по существу бесполезно: он неисправен и не достигает своей цели.

Любая память, выделенная программой, будет возвращена обратно в ОС после ее окончания. Это относится ко всем операционным системам, использующим виртуальную память, - подумайте о 32-битной или 64-битной современной ОС (современный здесь означает «сделанный в этом веке»). Если ОС не делает этого (или если нет ОС), вы уже знаете это.

Поэтому все проблемы с освобождением памяти применяются, когда ваша программа все еще работает.

Способ выделения памяти применяется только к этим единицам перевода, где вы определяете макрос. В тот момент, когда вы будете использовать внешнюю библиотеку (и вы в конце концов), вы вернетесь к квадрату:

// this is a function that creates a texture (for drawing to screen). IT'S ENTIRELY OUT OF YOUR CONTROL. 
SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer, 
           Uint32  format, 
           int   access, 
           int   w, 
           int   h); 

// somewhere in your code 
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STATIC, 128, 64); 
// now what 
+0

Это ответ, который я искал. Я не думал о внешних библиотеках, опирающихся на методы очистки ОС/ручные указатели сохранения. Возможно, я все еще использую функции MALLOC для моего кода, потому что я работаю над интерпретатором и хочу реализовать сборщик мусора, и я не могу всегда вручную сохранять указатели на память, потому что это не то, как работает интерпретатор (таким образом, я должен был бы определить более 1000 указателей), но в остальном вы правы: определение макроса для выделения памяти бесполезно. В моем случае определение пользовательских методов будет стоить того, но я сомневаюсь, что когда-нибудь буду использовать его после этого. – YoYoYonnY

+0

@YoYoYonnY Не уверен, что это правильный вывод. Хотя вы можете положиться на ОС, которые вернут память, * вы должны сначала закрыть программу *. Это означает, что для длительных программ вам все равно нужно освободить память - вы не можете просто пропустить ее. Проблема с вашим подходом заключается в том, что он не может быть обобщен для обработки любой библиотеки. Вам нужно создать более сложную схему - [см. Этот документ о стратегиях сбора мусора] (http://www3.nd.edu/~dthain/courses/cse40243/spring2006/gc-survey.pdf) – milleniumbug

+0

Спасибо за документ, я Я прочитаю это. Я полагаю, что '# define' - единственный способ добиться того, что я хочу, поскольку C не разрешает разглашение' void *'. (И, таким образом, я не могу использовать 'inline void * MALLOC (int ptr);') Я создам частные '* ALLOC' функции, поэтому мне не придется объявлять и освобождать каждую отдельную переменную. Я думаю, что 'MEMORY_SESSION (« Имя »)' будет идеальным решением для моделирования нескольких областей (таким образом, я могу разрешить одновременное интерпретирование нескольких файлов). EDIT: Я не могу думать. Если 'inline' не работает, то' # define' не работает либо ... – YoYoYonnY

Смежные вопросы