我使用这种方法在2d数组上做malloc,我的来源是 http://c-faq.com/aryptr/dynmuldimary.html和Modify malloc strategy for 2D Array so malloc succeeds:
int
main(int argc, char *argv[])
{
long **array = NULL;
array = malloc(5 * sizeof(long *));
for (int i = 0; i < 5; i++)
array[i] = malloc(3 * sizeof(long));
array[4][2] = 515;
array[4][3] = 212;
array[4][10000] = 3;
printf("%ld\n", array[4][10000]);
return 0;
}
我的问题是, 为什么在返回之前的最后三行中的任何一行的执行中都没有出现分段错误?它是否安全(忽略了自由的不存在)?
答案 0 :(得分:6)
您正在调用未定义的行为。顾名思义,未定义的行为未定义为导致分段错误。该代码可以将该内存的值设置为您提供的值,它可以完全忽略该分配,或者它可以为我们所知道的所有人订购披萨。
答案 1 :(得分:1)
malloc
只是内存如何分配给进程的一部分。
操作系统在整个页面中为进程提供内存,因此4kB或4MB(或其他......)大小的块 - 大。在用户空间中,该过程可以自由地按照自己喜欢的方式删除这些页面。
malloc
有2个角色:
来自操作系统的请求页
将这些页面划分为已分配的块
所以我打赌发生的事情是你在你拥有的页面中的其他地方着陆,而不是在你分配的一块中。就操作系统而言,没关系。
答案 2 :(得分:0)
写入您不拥有的内存不一定会导致分段错误。
当你覆盖其他指针时,后来尝试访问那些导致分段错误的指针。这就是为什么这些错误通常难以调试的原因。
答案 3 :(得分:0)
这是经典的堆损坏错误。它可能会或不会崩溃 - 取决于你有多幸运。
您正在覆盖最有可能未被使用的堆的部分或以不致命的方式破坏它。
答案 4 :(得分:0)
操作系统以页面形式为应用程序分配内存(通常为4 KB)。为了提高效率,可以使用大页面(例如2 MB)
永远不会分配第一页0,如果您尝试访问它,则会出现分段错误。例如访问0到4095之间的任何指针都会在大多数系统上出现分段错误。
但是,一旦为您分配了一个页面,您就可以读取和写入该页面的任何部分而不会出现分段错误。 (代码页通常不受写入保护)
当您使用malloc时,它确保您需要的页面在那里。但是,您可以访问您拥有的内存并以您喜欢的方式进行更改。 (假设你知道那是多少)
通常,这比有用更危险,但它可能有助于解释为什么以无效方式访问内存并不能保证分段错误。
注意:malloc的结构很小,例如8个字节,在块本身之前每个分配的内存块的开头,如果你破坏了这个,那么malloc
和free
将无法正常工作。