diff -r 4b97092aa4bd Modules/_lzmamodule.c --- a/Modules/_lzmamodule.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Modules/_lzmamodule.c Mon Apr 28 00:21:11 2014 +0200 @@ -221,10 +221,9 @@ parse_filter_spec_lzma(PyObject *spec) return NULL; } - options = (lzma_options_lzma *)PyMem_Malloc(sizeof *options); + options = (lzma_options_lzma *)PyMem_Calloc(1, sizeof *options); if (options == NULL) return PyErr_NoMemory(); - memset(options, 0, sizeof *options); if (lzma_lzma_preset(options, preset)) { PyMem_Free(options); @@ -266,10 +265,9 @@ parse_filter_spec_delta(PyObject *spec) return NULL; } - options = (lzma_options_delta *)PyMem_Malloc(sizeof *options); + options = (lzma_options_delta *)PyMem_Calloc(1, sizeof *options); if (options == NULL) return PyErr_NoMemory(); - memset(options, 0, sizeof *options); options->type = LZMA_DELTA_TYPE_BYTE; options->dist = dist; return options; @@ -290,10 +288,9 @@ parse_filter_spec_bcj(PyObject *spec) return NULL; } - options = (lzma_options_bcj *)PyMem_Malloc(sizeof *options); + options = (lzma_options_bcj *)PyMem_Calloc(1, sizeof *options); if (options == NULL) return PyErr_NoMemory(); - memset(options, 0, sizeof *options); options->start_offset = start_offset; return options; } diff -r 4b97092aa4bd Modules/_pickle.c --- a/Modules/_pickle.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Modules/_pickle.c Mon Apr 28 00:21:11 2014 +0200 @@ -635,13 +635,12 @@ PyMemoTable_New(void) memo->mt_used = 0; memo->mt_allocated = MT_MINSIZE; memo->mt_mask = MT_MINSIZE - 1; - memo->mt_table = PyMem_MALLOC(MT_MINSIZE * sizeof(PyMemoEntry)); + memo->mt_table = PyMem_Calloc(MT_MINSIZE, sizeof(PyMemoEntry)); if (memo->mt_table == NULL) { PyMem_FREE(memo); PyErr_NoMemory(); return NULL; } - memset(memo->mt_table, 0, MT_MINSIZE * sizeof(PyMemoEntry)); return memo; } @@ -660,7 +659,7 @@ PyMemoTable_Copy(PyMemoTable *self) /* The table we get from _New() is probably smaller than we wanted. Free it and allocate one that's the right size. */ PyMem_FREE(new->mt_table); - new->mt_table = PyMem_MALLOC(self->mt_allocated * sizeof(PyMemoEntry)); + new->mt_table = PyMem_Malloc(self->mt_allocated * sizeof(PyMemoEntry)); if (new->mt_table == NULL) { PyMem_FREE(new); PyErr_NoMemory(); @@ -755,7 +754,7 @@ static int /* Allocate new table. */ oldtable = self->mt_table; - self->mt_table = PyMem_MALLOC(new_size * sizeof(PyMemoEntry)); + self->mt_table = PyMem_Calloc(new_size, sizeof(PyMemoEntry)); if (self->mt_table == NULL) { self->mt_table = oldtable; PyErr_NoMemory(); @@ -763,7 +762,6 @@ static int } self->mt_allocated = new_size; self->mt_mask = new_size - 1; - memset(self->mt_table, 0, sizeof(PyMemoEntry) * new_size); /* Copy entries from the old table. */ to_process = self->mt_used; @@ -1314,12 +1312,11 @@ static int static PyObject ** _Unpickler_NewMemo(Py_ssize_t new_size) { - PyObject **memo = PyMem_MALLOC(new_size * sizeof(PyObject *)); + PyObject **memo = PyMem_Calloc(new_size, sizeof(PyObject *)); if (memo == NULL) { PyErr_NoMemory(); return NULL; } - memset(memo, 0, new_size * sizeof(PyObject *)); return memo; } diff -r 4b97092aa4bd Modules/_ssl.c --- a/Modules/_ssl.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Modules/_ssl.c Mon Apr 28 00:21:11 2014 +0200 @@ -3832,11 +3832,9 @@ static int _setup_ssl_threads(void) { if (_ssl_locks == NULL) { _ssl_locks_count = CRYPTO_num_locks(); _ssl_locks = (PyThread_type_lock *) - PyMem_Malloc(sizeof(PyThread_type_lock) * _ssl_locks_count); + PyMem_Calloc(_ssl_locks_count, sizeof(PyThread_type_lock)); if (_ssl_locks == NULL) return 0; - memset(_ssl_locks, 0, - sizeof(PyThread_type_lock) * _ssl_locks_count); for (i = 0; i < _ssl_locks_count; i++) { _ssl_locks[i] = PyThread_allocate_lock(); if (_ssl_locks[i] == NULL) { diff -r 4b97092aa4bd Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Modules/_testcapimodule.c Mon Apr 28 00:21:11 2014 +0200 @@ -2710,6 +2710,20 @@ test_pymem_alloc0(PyObject *self) { void *ptr; + ptr = PyMem_RawMalloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_RawMalloc(0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + + ptr = PyMem_RawCalloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_RawCalloc(0, 0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + ptr = PyMem_Malloc(0); if (ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, "PyMem_Malloc(0) returns NULL"); @@ -2717,6 +2731,13 @@ test_pymem_alloc0(PyObject *self) } PyMem_Free(ptr); + ptr = PyMem_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_Calloc(0, 0) returns NULL"); + return NULL; + } + PyMem_Free(ptr); + ptr = PyObject_Malloc(0); if (ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, "PyObject_Malloc(0) returns NULL"); @@ -2724,6 +2745,13 @@ test_pymem_alloc0(PyObject *self) } PyObject_Free(ptr); + ptr = PyObject_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyObject_Calloc(0, 0) returns NULL"); + return NULL; + } + PyObject_Free(ptr); + Py_RETURN_NONE; } @@ -2731,6 +2759,8 @@ typedef struct { PyMemAllocator alloc; size_t malloc_size; + size_t calloc_nelem; + size_t calloc_elsize; void *realloc_ptr; size_t realloc_new_size; void *free_ptr; @@ -2743,6 +2773,14 @@ static void* hook_malloc (void* ctx, siz return hook->alloc.malloc(hook->alloc.ctx, size); } +static void* hook_calloc (void* ctx, size_t nelem, size_t elsize) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->calloc_nelem = nelem; + hook->calloc_elsize = elsize; + return hook->alloc.calloc(hook->alloc.ctx, nelem, elsize); +} + static void* hook_realloc (void* ctx, void* ptr, size_t new_size) { alloc_hook_t *hook = (alloc_hook_t *)ctx; @@ -2765,16 +2803,14 @@ test_setallocators(PyMemAllocatorDomain const char *error_msg; alloc_hook_t hook; PyMemAllocator alloc; - size_t size, size2; + size_t size, size2, nelem, elsize; void *ptr, *ptr2; - hook.malloc_size = 0; - hook.realloc_ptr = NULL; - hook.realloc_new_size = 0; - hook.free_ptr = NULL; + memset(&hook, 0, sizeof(hook)); alloc.ctx = &hook; alloc.malloc = &hook_malloc; + alloc.calloc = &hook_calloc; alloc.realloc = &hook_realloc; alloc.free = &hook_free; PyMem_GetAllocator(domain, &hook.alloc); @@ -2831,6 +2867,33 @@ test_setallocators(PyMemAllocatorDomain goto fail; } + nelem = 2; + elsize = 5; + switch(domain) + { + case PYMEM_DOMAIN_RAW: ptr = PyMem_RawCalloc(nelem, elsize); break; + case PYMEM_DOMAIN_MEM: ptr = PyMem_Calloc(nelem, elsize); break; + case PYMEM_DOMAIN_OBJ: ptr = PyObject_Calloc(nelem, elsize); break; + default: ptr = NULL; break; + } + + if (ptr == NULL) { + error_msg = "calloc failed"; + goto fail; + } + + if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { + error_msg = "calloc invalid nelem or elsize"; + goto fail; + } + + switch(domain) + { + case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr); break; + case PYMEM_DOMAIN_MEM: PyMem_Free(ptr); break; + case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr); break; + } + Py_INCREF(Py_None); res = Py_None; goto finally; diff -r 4b97092aa4bd Modules/binascii.c --- a/Modules/binascii.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Modules/binascii.c Mon Apr 28 00:21:11 2014 +0200 @@ -1260,15 +1260,12 @@ binascii_a2b_qp_impl(PyModuleDef *module datalen = data->len; /* We allocate the output same size as input, this is overkill. - * The previous implementation used calloc() so we'll zero out the - * memory here too, since PyMem_Malloc() does not guarantee that. */ - odata = (unsigned char *) PyMem_Malloc(datalen); + odata = (unsigned char *) PyMem_Calloc(1, datalen); if (odata == NULL) { PyErr_NoMemory(); return NULL; } - memset(odata, 0, datalen); in = out = 0; while (in < datalen) { @@ -1438,15 +1435,12 @@ binascii_b2a_qp_impl(PyModuleDef *module } /* We allocate the output same size as input, this is overkill. - * The previous implementation used calloc() so we'll zero out the - * memory here too, since PyMem_Malloc() does not guarantee that. */ - odata = (unsigned char *) PyMem_Malloc(odatalen); + odata = (unsigned char *) PyMem_Calloc(1, odatalen); if (odata == NULL) { PyErr_NoMemory(); return NULL; } - memset(odata, 0, odatalen); in = out = linelen = 0; while (in < datalen) { diff -r 4b97092aa4bd Modules/faulthandler.c --- a/Modules/faulthandler.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Modules/faulthandler.c Mon Apr 28 00:21:11 2014 +0200 @@ -732,10 +732,9 @@ faulthandler_register_py(PyObject *self, return NULL; if (user_signals == NULL) { - user_signals = PyMem_Malloc(NSIG * sizeof(user_signal_t)); + user_signals = PyMem_Calloc(NSIG, sizeof(user_signal_t)); if (user_signals == NULL) return PyErr_NoMemory(); - memset(user_signals, 0, NSIG * sizeof(user_signal_t)); } user = &user_signals[signum]; diff -r 4b97092aa4bd Modules/hashtable.c --- a/Modules/hashtable.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Modules/hashtable.c Mon Apr 28 00:21:11 2014 +0200 @@ -128,11 +128,11 @@ round_size(size_t s) _Py_hashtable_allocator_t *allocator) { _Py_hashtable_t *ht; - size_t buckets_size; _Py_hashtable_allocator_t alloc; if (allocator == NULL) { alloc.malloc = PyMem_RawMalloc; + alloc.calloc = PyMem_RawCalloc; alloc.free = PyMem_RawFree; } else @@ -146,13 +146,11 @@ round_size(size_t s) ht->entries = 0; ht->data_size = data_size; - buckets_size = ht->num_buckets * sizeof(ht->buckets[0]); - ht->buckets = alloc.malloc(buckets_size); + ht->buckets = alloc.calloc(ht->num_buckets, sizeof(ht->buckets[0])); if (ht->buckets == NULL) { alloc.free(ht); return NULL; } - memset(ht->buckets, 0, buckets_size); ht->hash_func = hash_func; ht->compare_func = compare_func; @@ -396,7 +394,7 @@ int static void hashtable_rehash(_Py_hashtable_t *ht) { - size_t buckets_size, new_size, bucket; + size_t new_size, bucket; _Py_slist_t *old_buckets = NULL; size_t old_num_buckets; @@ -406,16 +404,14 @@ hashtable_rehash(_Py_hashtable_t *ht) old_num_buckets = ht->num_buckets; - buckets_size = new_size * sizeof(ht->buckets[0]); old_buckets = ht->buckets; - ht->buckets = ht->alloc.malloc(buckets_size); + ht->buckets = ht->alloc.calloc(new_size, sizeof(ht->buckets[0])); if (ht->buckets == NULL) { /* cancel rehash on memory allocation failure */ ht->buckets = old_buckets ; /* memory allocation failed */ return; } - memset(ht->buckets, 0, buckets_size); ht->num_buckets = new_size; diff -r 4b97092aa4bd Modules/hashtable.h --- a/Modules/hashtable.h Sun Apr 27 18:02:35 2014 +0100 +++ b/Modules/hashtable.h Mon Apr 28 00:21:11 2014 +0200 @@ -48,6 +48,9 @@ typedef struct { /* allocate a memory block */ void* (*malloc) (size_t size); + /* allocate a memory block initialized to zeros */ + void* (*calloc) (size_t nelem, size_t elsize); + /* release a memory block */ void (*free) (void *ptr); } _Py_hashtable_allocator_t; diff -r 4b97092aa4bd Objects/bytesobject.c --- a/Objects/bytesobject.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Objects/bytesobject.c Mon Apr 28 00:21:11 2014 +0200 @@ -71,6 +71,44 @@ static PyBytesObject *nullstring; PyBytes_FromStringAndSize()) or the length of the string in the `str' parameter (for PyBytes_FromString()). */ +static PyObject * +_PyBytes_FromSize(Py_ssize_t size, int zero) +{ + PyBytesObject *op; + assert(size >= 0); + if (size == 0 && (op = nullstring) != NULL) { +#ifdef COUNT_ALLOCS + null_strings++; +#endif + Py_INCREF(op); + return (PyObject *)op; + } + + if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { + PyErr_SetString(PyExc_OverflowError, + "byte string is too large"); + return NULL; + } + + /* Inline PyObject_NewVar */ + if (zero) + op = (PyBytesObject *)PyObject_Calloc(1, PyBytesObject_SIZE + size); + else + op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size); + if (op == NULL) + return PyErr_NoMemory(); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); + op->ob_shash = -1; + if (!zero) + op->ob_sval[size] = '\0'; + /* empty byte string singleton */ + if (size == 0) { + nullstring = op; + Py_INCREF(op); + } + return (PyObject *) op; +} + PyObject * PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) { @@ -80,13 +118,6 @@ PyBytes_FromStringAndSize(const char *st "Negative size passed to PyBytes_FromStringAndSize"); return NULL; } - if (size == 0 && (op = nullstring) != NULL) { -#ifdef COUNT_ALLOCS - null_strings++; -#endif - Py_INCREF(op); - return (PyObject *)op; - } if (size == 1 && str != NULL && (op = characters[*str & UCHAR_MAX]) != NULL) { @@ -97,26 +128,15 @@ PyBytes_FromStringAndSize(const char *st return (PyObject *)op; } - if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { - PyErr_SetString(PyExc_OverflowError, - "byte string is too large"); + op = (PyBytesObject *)_PyBytes_FromSize(size, 0); + if (op == NULL) return NULL; - } - - /* Inline PyObject_NewVar */ - op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); - if (op == NULL) - return PyErr_NoMemory(); - (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); - op->ob_shash = -1; - if (str != NULL) - Py_MEMCPY(op->ob_sval, str, size); - op->ob_sval[size] = '\0'; + if (str == NULL) + return (PyObject *) op; + + Py_MEMCPY(op->ob_sval, str, size); /* share short strings */ - if (size == 0) { - nullstring = op; - Py_INCREF(op); - } else if (size == 1 && str != NULL) { + if (size == 1) { characters[*str & UCHAR_MAX] = op; Py_INCREF(op); } @@ -2482,7 +2502,7 @@ bytes_new(PyTypeObject *type, PyObject * "argument"); return NULL; } - return PyBytes_FromString(""); + return PyBytes_FromStringAndSize(NULL, 0); } if (PyUnicode_Check(x)) { @@ -2532,11 +2552,9 @@ bytes_new(PyTypeObject *type, PyObject * return NULL; } else { - new = PyBytes_FromStringAndSize(NULL, size); + new = _PyBytes_FromSize(size, 1); if (new == NULL) return NULL; - if (size > 0) - memset(((PyBytesObject*)new)->ob_sval, 0, size); return new; } diff -r 4b97092aa4bd Objects/dictobject.c --- a/Objects/dictobject.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Objects/dictobject.c Mon Apr 28 00:21:11 2014 +0200 @@ -334,12 +334,11 @@ static PyObject *empty_values[1] = { NUL static PyDictKeysObject *new_keys_object(Py_ssize_t size) { PyDictKeysObject *dk; - Py_ssize_t i; - PyDictKeyEntry *ep0; assert(size >= PyDict_MINSIZE_SPLIT); assert(IS_POWER_OF_2(size)); - dk = PyMem_MALLOC(sizeof(PyDictKeysObject) + + dk = PyMem_Calloc(1, + sizeof(PyDictKeysObject) + sizeof(PyDictKeyEntry) * (size-1)); if (dk == NULL) { PyErr_NoMemory(); @@ -348,14 +347,8 @@ static PyDictKeysObject *new_keys_object DK_DEBUG_INCREF dk->dk_refcnt = 1; dk->dk_size = size; dk->dk_usable = USABLE_FRACTION(size); - ep0 = &dk->dk_entries[0]; - /* Hash value of slot 0 is used by popitem, so it must be initialized */ - ep0->me_hash = 0; - for (i = 0; i < size; i++) { - ep0[i].me_key = NULL; - ep0[i].me_value = NULL; - } dk->dk_lookup = lookdict_unicode_nodummy; + /* hash, key and value are all initialized to zero by calloc() */ return dk; } @@ -406,17 +399,14 @@ static PyObject * new_dict_with_shared_keys(PyDictKeysObject *keys) { PyObject **values; - Py_ssize_t i, size; + Py_ssize_t size; size = DK_SIZE(keys); - values = new_values(size); + values = PyMem_Calloc(size, sizeof(PyObject *)); if (values == NULL) { DK_DECREF(keys); return PyErr_NoMemory(); } - for (i = 0; i < size; i++) { - values[i] = NULL; - } return new_dict(keys, values); } diff -r 4b97092aa4bd Objects/listobject.c --- a/Objects/listobject.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Objects/listobject.c Mon Apr 28 00:21:11 2014 +0200 @@ -166,12 +166,11 @@ PyList_New(Py_ssize_t size) if (size <= 0) op->ob_item = NULL; else { - op->ob_item = (PyObject **) PyMem_MALLOC(nbytes); + op->ob_item = (PyObject **) PyMem_Calloc(1, nbytes); if (op->ob_item == NULL) { Py_DECREF(op); return PyErr_NoMemory(); } - memset(op->ob_item, 0, nbytes); } Py_SIZE(op) = size; op->allocated = size; diff -r 4b97092aa4bd Objects/moduleobject.c --- a/Objects/moduleobject.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Objects/moduleobject.c Mon Apr 28 00:21:11 2014 +0200 @@ -147,13 +147,12 @@ PyModule_Create2(struct PyModuleDef* mod return NULL; if (module->m_size > 0) { - m->md_state = PyMem_MALLOC(module->m_size); + m->md_state = PyMem_Calloc(1, module->m_size); if (!m->md_state) { PyErr_NoMemory(); Py_DECREF(m); return NULL; } - memset(m->md_state, 0, module->m_size); } d = PyModule_GetDict((PyObject*)m); diff -r 4b97092aa4bd Objects/setobject.c --- a/Objects/setobject.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Objects/setobject.c Mon Apr 28 00:21:11 2014 +0200 @@ -299,9 +299,10 @@ set_table_resize(PySetObject *so, Py_ssi memcpy(small_copy, oldtable, sizeof(small_copy)); oldtable = small_copy; } + memset(newtable, 0, sizeof(setentry) * newsize); } else { - newtable = PyMem_NEW(setentry, newsize); + newtable = PyMem_Calloc(newsize, sizeof(setentry)); if (newtable == NULL) { PyErr_NoMemory(); return -1; @@ -312,7 +313,6 @@ set_table_resize(PySetObject *so, Py_ssi assert(newtable != oldtable); so->table = newtable; so->mask = newsize - 1; - memset(newtable, 0, sizeof(setentry) * newsize); i = so->used; so->used = 0; so->fill = 0; diff -r 4b97092aa4bd Objects/tupleobject.c --- a/Objects/tupleobject.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Objects/tupleobject.c Mon Apr 28 00:21:11 2014 +0200 @@ -66,7 +66,7 @@ PyObject * PyTuple_New(Py_ssize_t size) { PyTupleObject *op; - Py_ssize_t i; + Py_ssize_t obj_size; if (size < 0) { PyErr_BadInternalCall(); return NULL; @@ -92,6 +92,7 @@ PyTuple_New(Py_ssize_t size) Py_TYPE(op) = &PyTuple_Type; #endif _Py_NewReference((PyObject *)op); + memset(op->ob_item, 0, size * sizeof(op->ob_item[0])); } else #endif @@ -101,12 +102,12 @@ PyTuple_New(Py_ssize_t size) sizeof(PyObject *)) / sizeof(PyObject *)) { return PyErr_NoMemory(); } - op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size); + obj_size = _PyObject_VAR_SIZE(&PyTuple_Type, size); + op = (PyTupleObject *)_PyObject_GC_Calloc(1, obj_size); if (op == NULL) return NULL; + PyObject_INIT_VAR(op, &PyTuple_Type, size); } - for (i=0; i < size; i++) - op->ob_item[i] = NULL; #if PyTuple_MAXSAVESIZE > 0 if (size == 0) { free_list[0] = op; diff -r 4b97092aa4bd Objects/typeobject.c --- a/Objects/typeobject.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Objects/typeobject.c Mon Apr 28 00:21:11 2014 +0200 @@ -884,15 +884,13 @@ PyType_GenericAlloc(PyTypeObject *type, /* note that we need to add one, for the sentinel */ if (PyType_IS_GC(type)) - obj = _PyObject_GC_Malloc(size); + obj = _PyObject_GC_Calloc(1, size); else - obj = (PyObject *)PyObject_MALLOC(size); + obj = (PyObject *)PyObject_Calloc(1, size); if (obj == NULL) return PyErr_NoMemory(); - memset(obj, '\0', size); - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) Py_INCREF(type); diff -r 4b97092aa4bd Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Sun Apr 27 18:02:35 2014 +0100 +++ b/Objects/bytearrayobject.c Mon Apr 28 00:59:33 2014 +0200 @@ -813,9 +813,21 @@ bytearray_init(PyByteArrayObject *self, } else { if (count > 0) { - if (PyByteArray_Resize((PyObject *)self, count)) + void *sval; + Py_ssize_t alloc; + + assert (Py_SIZE(self) == 0); + + alloc = count + 1; + sval = PyObject_Calloc(1, alloc); + if (sval == NULL) return -1; - memset(PyByteArray_AS_STRING(self), 0, count); + + PyObject_Free(self->ob_bytes); + + self->ob_bytes = self->ob_start = sval; + Py_SIZE(self) = count; + self->ob_alloc = alloc; } return 0; }