Этот кастомный 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 ответа

Решение

Есть некоторые проблемы:

  1. Самая большая проблема - выравнивание. Возвращаемый указатель должен быть выровнен. Так как это 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);
    
  2. Нет обнаружения для нехватки памяти.

  3. Избегайте повторного использования стандартных имен библиотек. Код может define их позже, при необходимости.

    // void* malloc(int size, int* bytesUsed, uchar* memory);
    void* RG_malloc(int size, int* bytesUsed, uchar* memory);
    
    // if needed
    #define malloc RF_malloc
    
  4. malloc() ожидает другой тип для распределений: size_tне int,

    // void* malloc(int size, int* bytesUsed, uchar* memory);
    void* malloc(size_t size, size_t* bytesUsed, uchar* memory);
    
  5. В ролях не нужно.

    // return (void*)(memory+startIdx);
    return memory + startIdx;
    
  6. Более понятный в использовании 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, так как вы сказали, что вам не нужно освобождать.

Другие вопросы по тегам