Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我可以访问Python中看似任意的内存地址?_Python_Memory_Numpy_Cpython - Fatal编程技术网

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

为什么我可以访问Python中看似任意的内存地址?,python,memory,numpy,cpython,Python,Memory,Numpy,Cpython,在NumPy中使用时,我意识到您可以轻松地越过阵列的边界: >>> 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)

在NumPy中使用时,我意识到您可以轻松地越过阵列的边界:

>>> 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下使用或访问。这通常会给你确切的要求,但它不是非常友好的用户
  • C运行时堆,可通过和
    free(3)
    访问。这可能会也可能不会立即将释放的内存返回到操作系统。如果性能更好的话,它还可以将分配四舍五入到最近的页面。这通常按照(1)实现

  • 大多数应用程序,包括NumPy和Python,使用(2)而不是(1)(或者它们在(2)之上实现自己的内存分配器)。结果,根据(2)无效的存储器根据(1)仍然有效。只有在违反方法(1)的规则时,才能获得segfault。也有可能您正在与堆上的其他活动对象交互,这极有可能导致您的程序以任意方式出现错误行为。

    Python和numpy是用C构建的,C没有内置内存保护。内存在“堆”中分配,堆是一大块内存。因为所有的对象都分配在那里,所以内存区域非常大,并且充满了任何类型的对象。写入此内存可能会使您的程序崩溃。

    您是否阅读过例如?是的,没有解释这一点。我认为说SEGFULT仅因违反方法(1)而导致是不正确的。根据我自己的调查(下面的答案),只有内存映射才能定义何时抛出segfault。还是我错了?警卫页面呢?我不太明白。尽管操作系统已经为读取访问准备了一个块,但在尝试读取时仍然可能引发错误吗?@jasaarim:malloc使用mmap和brk。Python使用malloc。“内存映射”是mmap,它本身就是(1)的一部分。但如果不是这样,我会感谢你的回答。这很有帮助,也让我更多地思考这个问题。哦,对不起,现在我明白了。是的,你可能是对的。