为什么我可以在Python中访问看似任意的内存地址?

我在NumPy中使用strides进行游戏,我意识到您可以轻松地超越数组的界限: import numpy as np from numpy.lib.stride_tricks import as_strided a = np.array([1], dtype=np.int8) as_strided(a, shap...

我在NumPy中使用strides进行游戏,我意识到您可以轻松地超越数组的界限:

>>> import numpy as np
>>> from numpy.lib.stride_tricks import as_strided
>>> a = np.array([1], dtype=np.int8)
>>> as_strided(a, shape=(2,), strides=(1,))
array([  1, -28], dtype=int8)

这样,我可以读取数组外部的字节,也可以写入其中.但是我不知道这怎么可能.为什么操作系统没有阻止我?在抛出分段错误之前,我似乎可以离开此阵列至少100 KB.

我唯一想到的就是该内存空间是由我的Python进程直接分配的. NumPy会这样做吗?这个空间有固定的大小吗?还有什么其他对象?

解决方法:

这里有两种不同的内存分配器在起作用:

>操作系统,可在Unix下通过以下方式访问: brk(2)或mmap(2).这通常会提供您所需的确切信息,但它不是很友好.
> C运行时堆,可通过malloc(3)和free(3)访问.这可能会或可能不会立即将释放的内存返回给操作系统.如果性能更高,它也可以将分配向上舍入到最近的页面.这通常根据(1)来实现.

大多数应用程序,包括NumPy和Python,都使用(2)而不是(1)(或者它们在(2)之上实现了自己的内存分配器).结果,根据(2)无效的内存可能仍然根据(1)有效.如果违反方法(1)的规则,则只会发生段错误.您还可能与堆上的其他活动对象进行交互,这很可能导致程序以任意方式异常运行,即even if you are not changing anything.

本文标题为:为什么我可以在Python中访问看似任意的内存地址?

基础教程推荐