Skip to content

Commit 37378f8

Browse files
committed
py: Clean up edge cases of malloc/realloc/free.
1 parent f5d6979 commit 37378f8

2 files changed

Lines changed: 20 additions & 28 deletions

File tree

py/gc.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,12 @@ void *gc_realloc(void *ptr_in, mp_uint_t n_bytes) {
546546
return gc_alloc(n_bytes, false);
547547
}
548548

549+
// check for pure free
550+
if (n_bytes == 0) {
551+
gc_free(ptr_in);
552+
return NULL;
553+
}
554+
549555
mp_uint_t ptr = (mp_uint_t)ptr_in;
550556

551557
// sanity check the ptr

py/malloc.c

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,8 @@ STATIC size_t peak_bytes_allocated = 0;
6363
#endif // MICROPY_ENABLE_GC
6464

6565
void *m_malloc(size_t num_bytes) {
66-
if (num_bytes == 0) {
67-
return NULL;
68-
}
6966
void *ptr = malloc(num_bytes);
70-
if (ptr == NULL) {
67+
if (ptr == NULL && num_bytes != 0) {
7168
return m_malloc_fail(num_bytes);
7269
}
7370
#if MICROPY_MEM_STATS
@@ -81,9 +78,6 @@ void *m_malloc(size_t num_bytes) {
8178

8279
void *m_malloc_maybe(size_t num_bytes) {
8380
void *ptr = malloc(num_bytes);
84-
if (ptr == NULL) {
85-
return NULL;
86-
}
8781
#if MICROPY_MEM_STATS
8882
total_bytes_allocated += num_bytes;
8983
current_bytes_allocated += num_bytes;
@@ -95,11 +89,8 @@ void *m_malloc_maybe(size_t num_bytes) {
9589

9690
#if MICROPY_ENABLE_FINALISER
9791
void *m_malloc_with_finaliser(size_t num_bytes) {
98-
if (num_bytes == 0) {
99-
return NULL;
100-
}
10192
void *ptr = malloc_with_finaliser(num_bytes);
102-
if (ptr == NULL) {
93+
if (ptr == NULL && num_bytes != 0) {
10394
return m_malloc_fail(num_bytes);
10495
}
10596
#if MICROPY_MEM_STATS
@@ -114,19 +105,16 @@ void *m_malloc_with_finaliser(size_t num_bytes) {
114105

115106
void *m_malloc0(size_t num_bytes) {
116107
void *ptr = m_malloc(num_bytes);
117-
if (ptr != NULL) {
118-
memset(ptr, 0, num_bytes);
108+
if (ptr == NULL && num_bytes != 0) {
109+
return m_malloc_fail(num_bytes);
119110
}
111+
memset(ptr, 0, num_bytes);
120112
return ptr;
121113
}
122114

123115
void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes) {
124-
if (new_num_bytes == 0) {
125-
free(ptr);
126-
return NULL;
127-
}
128116
void *new_ptr = realloc(ptr, new_num_bytes);
129-
if (new_ptr == NULL) {
117+
if (new_ptr == NULL && new_num_bytes != 0) {
130118
return m_malloc_fail(new_num_bytes);
131119
}
132120
#if MICROPY_MEM_STATS
@@ -146,28 +134,26 @@ void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes) {
146134

147135
void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes) {
148136
void *new_ptr = realloc(ptr, new_num_bytes);
149-
if (new_ptr == NULL) {
150-
return NULL;
151-
}
152137
#if MICROPY_MEM_STATS
153138
// At first thought, "Total bytes allocated" should only grow,
154139
// after all, it's *total*. But consider for example 2K block
155140
// shrunk to 1K and then grown to 2K again. It's still 2K
156141
// allocated total. If we process only positive increments,
157142
// we'll count 3K.
158-
size_t diff = new_num_bytes - old_num_bytes;
159-
total_bytes_allocated += diff;
160-
current_bytes_allocated += diff;
161-
UPDATE_PEAK();
143+
// Also, don't count failed reallocs.
144+
if (!(new_ptr == NULL && new_num_bytes != 0)) {
145+
size_t diff = new_num_bytes - old_num_bytes;
146+
total_bytes_allocated += diff;
147+
current_bytes_allocated += diff;
148+
UPDATE_PEAK();
149+
}
162150
#endif
163151
DEBUG_printf("realloc %p, %d, %d : %p\n", ptr, old_num_bytes, new_num_bytes, new_ptr);
164152
return new_ptr;
165153
}
166154

167155
void m_free(void *ptr, size_t num_bytes) {
168-
if (ptr != NULL) {
169-
free(ptr);
170-
}
156+
free(ptr);
171157
#if MICROPY_MEM_STATS
172158
current_bytes_allocated -= num_bytes;
173159
#endif

0 commit comments

Comments
 (0)