Cleanup: python: Replace 'void' MEM_[cm]allocN with templated, type-safe MEM_[cm]allocN<T>.

The main issue of 'type-less' standard C allocations is that there is no check on
allocated type possible.

This is a serious source of annoyance (and crashes) when making some
low-level structs non-trivial, as tracking down all usages of these
structs in higher-level other structs and their allocation is... really
painful.

MEM_[cm]allocN<T> templates on the other hand do check that the
given type is trivial, at build time (static assert), which makes such issue...
trivial to catch.

NOTE: New code should strive to use MEM_new (i.e. allocation and
construction) as much as possible, even for trivial PoD types.

Pull Request: https://projects.blender.org/blender/blender/pulls/135852
This commit is contained in:
Bastien Montagne
2025-03-12 11:21:53 +01:00
committed by Bastien Montagne
parent 9f697c7cc6
commit bb89c89e7f
13 changed files with 45 additions and 59 deletions

View File

@@ -692,8 +692,7 @@ static Buffer *BGL_MakeBuffer_FromData(
Py_XINCREF(parent);
buffer->parent = parent;
buffer->ndimensions = ndimensions;
buffer->dimensions = static_cast<int *>(
MEM_mallocN(ndimensions * sizeof(int), "Buffer dimensions"));
buffer->dimensions = MEM_malloc_arrayN<int>(size_t(ndimensions), "Buffer dimensions");
memcpy(buffer->dimensions, dimensions, ndimensions * sizeof(int));
buffer->type = type;
buffer->buf.asvoid = buf;

View File

@@ -2442,7 +2442,7 @@ static int BPy_IDArray_getbuffer(BPy_IDArray *self, Py_buffer *view, int flags)
view->itemsize = itemsize;
view->format = (char *)idp_format_from_array_type(prop->subtype);
Py_ssize_t *shape = static_cast<Py_ssize_t *>(MEM_mallocN(sizeof(Py_ssize_t), __func__));
Py_ssize_t *shape = MEM_mallocN<Py_ssize_t>(__func__);
shape[0] = prop->len;
view->shape = shape;

View File

@@ -178,7 +178,7 @@ static bool idprop_ui_data_update_int_default(IDProperty *idprop,
}
Py_ssize_t len = PySequence_Size(default_value);
int *new_default_array = (int *)MEM_malloc_arrayN(len, sizeof(int), __func__);
int *new_default_array = MEM_malloc_arrayN<int>(size_t(len), __func__);
if (PyC_AsArray(
new_default_array, sizeof(int), default_value, len, &PyLong_Type, "ui_data_update") ==
-1)
@@ -338,7 +338,7 @@ static bool idprop_ui_data_update_bool_default(IDProperty *idprop,
}
Py_ssize_t len = PySequence_Size(default_value);
int8_t *new_default_array = (int8_t *)MEM_malloc_arrayN(len, sizeof(int8_t), __func__);
int8_t *new_default_array = MEM_malloc_arrayN<int8_t>(size_t(len), __func__);
if (PyC_AsArray(new_default_array,
sizeof(int8_t),
default_value,
@@ -428,7 +428,7 @@ static bool idprop_ui_data_update_float_default(IDProperty *idprop,
}
Py_ssize_t len = PySequence_Size(default_value);
double *new_default_array = (double *)MEM_malloc_arrayN(len, sizeof(double), __func__);
double *new_default_array = MEM_malloc_arrayN<double>(size_t(len), __func__);
if (PyC_AsArray(new_default_array,
sizeof(double),
default_value,

View File

@@ -1614,8 +1614,8 @@ bool PyC_RunString_AsStringAndSize(const char *imports[],
ok = false;
}
else {
char *val_alloc = static_cast<char *>(MEM_mallocN(val_len + 1, __func__));
memcpy(val_alloc, val, val_len + 1);
char *val_alloc = MEM_malloc_arrayN<char>(size_t(val_len) + 1, __func__);
memcpy(val_alloc, val, (size_t(val_len) + 1) * sizeof(*val_alloc));
*r_value = val_alloc;
*r_value_size = val_len;
ok = true;
@@ -1658,8 +1658,8 @@ bool PyC_RunString_AsStringAndSizeOrNone(const char *imports[],
ok = false;
}
else {
char *val_alloc = static_cast<char *>(MEM_mallocN(val_len + 1, __func__));
memcpy(val_alloc, val, val_len + 1);
char *val_alloc = MEM_malloc_arrayN<char>(size_t(val_len) + 1, __func__);
memcpy(val_alloc, val, (size_t(val_len) + 1) * sizeof(val_alloc));
*r_value = val_alloc;
*r_value_size = val_len;
ok = true;