Этот кастомный malloc в порядке?
Мне нужно написать собственный malloc для программирования на GPU. Будет ли это работать правильно?
void* malloc(int size, int* bytesUsed, uchar* memory){
int startIdx = (*bytesUsed);
(*bytesUsed) += size;
return (void*)(memory+startIdx);
}
Я новичок в программировании на C, возможно, я сделал ошибки, связанные с арифметикой указателей, или что-то в этом роде... bytesUsed
дает вам индекс в memory
первого свободного адреса, поэтому вы увеличиваете его на size
а затем вернуть увеличенный индекс в качестве указателя.
2 ответа
Есть некоторые проблемы:
Самая большая проблема - выравнивание. Возвращаемый указатель должен быть выровнен. Так как это
malloc()
не указан тип указателя, используйтеmax_align_t
"который является типом объекта, выравнивание которого настолько велико, насколько это поддерживается реализацией во всех контекстах" C11dr §7.19 2. Примечание:*bytesUsed
тоже нужно это выравнивание. Поэтому применять аналогичный код следует, если другой код влияет на него.if (size%sizeof(max_align_t)) { size += sizeof(max_align_t) - size%sizeof(max_align_t); } // or size = (size + sizeof(max_align_t) - 1)/sizeof(max_align_t)*sizeof(max_align_t);
Нет обнаружения для нехватки памяти.
Избегайте повторного использования стандартных имен библиотек. Код может
define
их позже, при необходимости.// void* malloc(int size, int* bytesUsed, uchar* memory); void* RG_malloc(int size, int* bytesUsed, uchar* memory); // if needed #define malloc RF_malloc
malloc()
ожидает другой тип для распределений:size_t
неint
,// void* malloc(int size, int* bytesUsed, uchar* memory); void* malloc(size_t size, size_t* bytesUsed, uchar* memory);
В ролях не нужно.
// return (void*)(memory+startIdx); return memory + startIdx;
Более понятный в использовании
unsigned char
чемuchar
что, надеюсь, не что-то еще.
Собираем все это вместе
void* malloc(size_t size, size_t* bytesUsed, unsigned char* memory){
size = (size + sizeof(max_align_t) - 1)/sizeof(max_align_t)*sizeof(max_align_t);
if (RG_ALLOC_SIZE - *bytesUsed > size) {
return NULL;
}
size_t startIdx = *bytesUsed; // See note above concerning alignment.
*bytesUsed += size;
return memory + startIdx;
}
Дополнительно, RG_free()
не закодировано Если это необходимо, эта простая схема распределения потребует значительных дополнений.
Я не уверен, что это простое решение на основе стека подойдет вам
#include <stdint.h>
const size_t ALLOCSIZE = 1024;
typedef uint8_t byte;
static byte buf[ALLOCSIZE];
static byte *pbuf = buf;
byte *alloc(size_t n)
{
/* if there is room */
if (buf + ALLOCSIZE - pbuf >= n) {
pbuf += n;
return pbuf - n;
} else
return NULL;
}
Я не предоставил free
, так как вы сказали, что вам не нужно освобождать.