void *_malloc_or_die(size_t size, const char *file, int line) { void *result; /* fail on attempted allocations of 0 */ if (size == 0) fatalerror("Attempted to malloc zero bytes (%s:%d)", file, line); /* allocate and return if we succeeded */ #ifdef MALLOC_DEBUG result = malloc_file_line(size, file, line); #else result = malloc(size); #endif if (result != NULL) { #ifdef MAME_DEBUG rand_memory(result, size); #endif return result; } /* otherwise, die horribly */ fatalerror("Failed to allocate %d bytes (%s:%d)", (int)size, file, line); }
void *realloc_file_line(void *memory, size_t size, const char *file, int line) { void *newmemory = NULL; // if size is non-zero, we need to reallocate memory if (size != 0) { // allocate space for the new amount newmemory = malloc_file_line(size, file, line); if (newmemory == NULL) return NULL; // if we have an old pointer, copy it if (memory != NULL) { memory_entry *entry = find_entry(memory); if (entry == NULL) { if (winalloc_in_main_code) { fprintf(stderr, "Error: realloc a non-existant block\n"); osd_break_into_debugger("Error: realloc a non-existant block"); } } else memcpy(newmemory, memory, (size < entry->size) ? size : entry->size); } } // if we have an original pointer, free it if (memory != NULL) free(memory); return newmemory; }
void *calloc_file_line(size_t size, size_t count, const char *file, int line) { // first allocate the memory void *memory = malloc_file_line(size * count, file, line); if (memory == NULL) return NULL; // then memset it memset(memory, 0, size * count); return memory; }
void *realloc_internal(void *memory, size_t size, const char *file, int line, bool array) { fprintf(stderr, "realloc_internal called for %p in %s(%d)!\n", memory, file, line); if(size == 0) { return nullptr; } if(memory == nullptr) { return malloc_file_line(size, file, line, array, false, false); } // find the memory entry memory_entry *entry = memory_entry::find(memory); // warn about untracked reallocs if (entry == nullptr) { fprintf(stderr, "Error: attempt to realloc untracked memory %p in %s(%d)!\n", memory, file, line); osd_break_into_debugger("Error: attempt to realloc untracked memory"); return memory; } // this is used internally and should always be an array if(!array || !entry->m_array) { fprintf(stderr, "Error: attempt to realloc non-array memory %p in %s(%d). realloc_internal should never be called directly!\n", memory, file, line); osd_break_into_debugger("Error: attempt to realloc non-array memory"); } size_t o_size = entry->m_size; void *new_buf = malloc_file_line(size, file, line, array, false, false); if(new_buf == nullptr) { fprintf(stderr, "Error: realloc: unable to allocate new buffer %p in %s(%d)!\n", memory, file, line); return nullptr; } memcpy(new_buf, memory, (o_size < size) ? o_size : size); free_file_line(memory, file, line, array); return new_buf; }
void *operator new[](std::size_t size, const char *file, int line, const zeromem_t &) throw (std::bad_alloc) { return malloc_file_line(size, file, line, true, true, true); }
// file/line new/delete operators void *operator new(std::size_t size, const char *file, int line) throw (std::bad_alloc) { return malloc_file_line(size, file, line, false, true, false); }
void* operator new[](std::size_t size, const std::nothrow_t&) throw() { return malloc_file_line(size, nullptr, 0, true, false, false); }
void *operator new[](std::size_t size) throw (std::bad_alloc) { return malloc_file_line(size, nullptr, 0, true, true, false); }
void* operator new(std::size_t size,const std::nothrow_t&) throw() { return malloc_file_line(size, NULL, 0, false, false, false); }
// standard new/delete operators (try to avoid using) void *operator new(std::size_t size) throw (std::bad_alloc) { return malloc_file_line(size, NULL, 0, false, true, false); }
void *CLIB_DECL malloc(size_t size) { return malloc_file_line(size, NULL, 0); }