Repository navigation
Description
Describe the issue:
Some string operations allocate much more temporary memory than their inputs and outputs require, even for arrays containing just one element:
StringDTypeslicing builds an index for the entire input, even when selecting one character.StringDTypereplacement with an empty pattern sizes its temporary as though every insertion were performed, even withcount=1.- Some casts allocate buffers for 128 elements regardless of the array's length. Converting one integer to
S1048576has about 130 MiB of peak traced allocations for a 1 MiB output. This also affects operations such ascenter,ljust, andrjustthrough internal casts.
These allocations can cause avoidable MemoryErrors or process termination when individual strings or fixed-width string dtypes are large. Temporary storage should be bounded or sized to the work actually required.
Reproduce the code example:
Save as repro.py. This example runs on Linux and macOS. Inputs are created before imposing a limit of 6 MiB above current virtual memory usage; each result needs at most about 1 MiB.
import os
import resource
import subprocess
import sys
import numpy as np
MiB = 1024**2
text = np.array(['x' * MiB], dtype='T')
number = np.array([123])
padded = np.array([b'x'], dtype=f'S{MiB}')
operations = {
'slice': lambda: np.strings.slice(text, 0, 1),
'replace': lambda: np.strings.replace(text, '', 'prefix: ', count=1),
'astype': lambda: number.astype(f'S{MiB}'),
'center': lambda: np.strings.center(padded, 1),
}
# ps reports virtual memory in KiB on both Linux and macOS.
vsz = int(subprocess.check_output(['ps', '-o', 'vsz=', '-p', str(os.getpid())]))
limit = vsz * 1024 + 6 * MiB
resource.setrlimit(resource.RLIMIT_AS, (limit, limit))
result = operations[sys.argv[1]]()
print('Succeeded')Run each operation in a separate process:
python repro.py slice
python repro.py replace
python repro.py astype
python repro.py centerError message:
slice aborts (Linux message shown):
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
replace raises MemoryError: Failed to allocate string in replace. astype and center raise MemoryError.
Python and NumPy Versions:
2.6.0.dev0
3.14.8 (main, Oct 9 2026, 20:43:58) [GCC 14.2.1 20250110 (Red Hat 14.2.1-11)]
Runtime Environment:
Reproduced on Linux aarch64 and macOS arm64 with local NumPy development builds.
How does this issue affect you or how did you find it:
Found while investigating memory use with large individual strings. I plan to submit two PRs using shared memorylimit testing machinery. One PR to use new StringDType slice/replace algorithms, and one to add a byte size limit for casting buffers.
Activity