File indexing completed on 2025-12-11 10:26:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #ifndef GMEM_H
0028 #define GMEM_H
0029
0030 #include <cassert>
0031 #include <cstring>
0032 #include <cstdlib>
0033 #include <cstdio>
0034
0035 #include "GooCheckedOps.h"
0036
0037
0038 inline void *gmalloc(size_t size, bool checkoverflow = false)
0039 {
0040 if (size == 0) {
0041 return nullptr;
0042 }
0043
0044 if (void *p = std::malloc(size)) {
0045 return p;
0046 }
0047
0048 std::fputs("Out of memory\n", stderr);
0049
0050 if (checkoverflow) {
0051 return nullptr;
0052 }
0053
0054 std::abort();
0055 }
0056
0057 inline void *gmalloc_checkoverflow(size_t size)
0058 {
0059 return gmalloc(size, true);
0060 }
0061
0062
0063 inline void gfree(void *p)
0064 {
0065 std::free(p);
0066 }
0067
0068
0069
0070 inline void *grealloc(void *p, size_t size, bool checkoverflow = false)
0071 {
0072 if (size == 0) {
0073 gfree(p);
0074 return nullptr;
0075 }
0076
0077 if (void *q = p ? std::realloc(p, size) : std::malloc(size)) {
0078 return q;
0079 }
0080
0081 std::fputs("Out of memory\n", stderr);
0082
0083 if (checkoverflow) {
0084 return nullptr;
0085 }
0086
0087 std::abort();
0088 }
0089
0090 inline void *grealloc_checkoverflow(void *p, size_t size)
0091 {
0092 return grealloc(p, size, true);
0093 }
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 inline void *gmallocn(int count, int size, bool checkoverflow = false)
0105 {
0106 if (count == 0) {
0107 return nullptr;
0108 }
0109
0110 int bytes;
0111 if (count < 0 || size <= 0 || checkedMultiply(count, size, &bytes)) {
0112 std::fputs("Bogus memory allocation size\n", stderr);
0113
0114 if (checkoverflow) {
0115 return nullptr;
0116 }
0117
0118 std::abort();
0119 }
0120
0121 return gmalloc(bytes, checkoverflow);
0122 }
0123
0124 inline void *gmallocn_checkoverflow(int count, int size)
0125 {
0126 return gmallocn(count, size, true);
0127 }
0128
0129 inline void *gmallocn3(int width, int height, int size, bool checkoverflow = false)
0130 {
0131 if (width == 0 || height == 0) {
0132 return nullptr;
0133 }
0134
0135 int count;
0136 int bytes;
0137 if (width < 0 || height < 0 || size <= 0 || checkedMultiply(width, height, &count) || checkedMultiply(count, size, &bytes)) {
0138 std::fputs("Bogus memory allocation size\n", stderr);
0139
0140 if (checkoverflow) {
0141 return nullptr;
0142 }
0143
0144 std::abort();
0145 }
0146
0147 return gmalloc(bytes, checkoverflow);
0148 }
0149
0150 inline void *greallocn(void *p, int count, int size, bool checkoverflow = false, bool free_p = true)
0151 {
0152 if (count == 0) {
0153 if (free_p) {
0154 gfree(p);
0155 }
0156 return nullptr;
0157 }
0158
0159 int bytes;
0160 if (count < 0 || size <= 0 || checkedMultiply(count, size, &bytes)) {
0161 std::fputs("Bogus memory allocation size\n", stderr);
0162
0163 if (checkoverflow) {
0164 if (free_p) {
0165 gfree(p);
0166 }
0167 return nullptr;
0168 }
0169
0170 std::abort();
0171 }
0172
0173 assert(bytes > 0);
0174 if (void *q = grealloc(p, bytes, checkoverflow)) {
0175 return q;
0176 }
0177 if (free_p) {
0178 gfree(p);
0179 }
0180 return nullptr;
0181 }
0182
0183 inline void *greallocn_checkoverflow(void *p, int count, int size)
0184 {
0185 return greallocn(p, count, size, true);
0186 }
0187
0188
0189 inline char *copyString(const char *s)
0190 {
0191 char *r = static_cast<char *>(gmalloc(std::strlen(s) + 1, false));
0192 return std::strcpy(r, s);
0193 }
0194
0195
0196 inline char *copyString(const char *s, size_t n)
0197 {
0198 char *r = static_cast<char *>(gmalloc(n + 1, false));
0199 r[n] = '\0';
0200 return std::strncpy(r, s, n);
0201 }
0202
0203 #endif