3 回答
TA贡献1805条经验 获得超9个赞
TA贡献2003条经验 获得超2个赞
malloc()
malloc()
sbrk
mmap
free()
glibc
malloc()
free()
glibc
手册页malloc()
malloc()分配大小字节并返回指向分配内存的指针。 内存没有清除。如果大小为0,那么malloc()将返回NULL,或者返回一个以后可以成功传递给Free()的唯一指针值。
TA贡献1865条经验 获得超7个赞
简短答覆:
没有,只是碰巧在你的情况下是零。
(此外,您的测试用例没有显示数据为零。它只显示一个元素为零的情况。)
详细答覆:
当你打电话malloc()
会发生两件事之一:
- 它回收以前分配并从同一进程中释放的内存。
- 它从操作系统请求新页面。
在第一种情况下,内存将包含以前分配的剩余数据。所以不会是零。这是执行少量分配时的通常情况。
在第二种情况下,内存将来自操作系统。当程序内存耗尽时,或者当您请求一个非常大的分配时,就会发生这种情况。(与您的示例中的情况一样)
以下是问题所在:来自操作系统的内存将被归零保安理由*
当操作系统给您内存时,它可以从不同的进程中释放出来。以便内存可以包含敏感信息,如密码。因此,为了防止您读取这些数据,操作系统将在将其提供给您之前将其归零。
*我注意到C标准对此没有任何规定。这是严格意义上的OS行为。因此,这种零化可能存在,也可能不存在于安全性不受关注的系统上。
为了给这方面提供更多的性能背景:
正如@R.在注释中提到的,这个零化是为什么您应该始终使用calloc()
而不是malloc()
+ memset()
. calloc()
可以利用这一事实来避免单独的memset()
.
另一方面,这种归零有时是性能瓶颈。在一些数值应用中(例如格格不入的FFT),您需要分配一大块划痕内存。使用它来执行任何算法,然后释放它。
在这些情况下,零化是不必要的,相当于纯粹的开销。
我所见过的最极端的例子是20秒的零开销,这是一个70秒操作的零开销,它有一个48 GB的划痕缓冲区。(大约30%的间接费用。)(诚然:这台机器确实缺乏内存带宽。)
显而易见的解决方案是简单地手动重用内存。但这往往需要突破已建立的接口。(特别是如果它是库例程的一部分)
- 3 回答
- 0 关注
- 1185 浏览
添加回答
举报