我使用此方法对2d数组进行malloc,我的源是http://c-faq.com/aryptr/dynmuldimary.html和修改二维数组的malloc策略,使malloc成功:
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("%ldn", array[4][10000]);
return 0;
}
我的问题是,为什么在执行返回前的最后三行代码时没有出现分段错误?它安全吗(忽略free的不存在)? 您正在调用未定义行为。未定义行为,顾名思义,并没有定义为导致分段错误。这段代码可以将内存的值设置为你给它的值,它可以完全忽略赋值,或者它可以点披萨
malloc
只是分配给进程内存的一部分。
内存是由操作系统以整个页面的形式分配给进程的,所以4kB或4MB(或其他…)大小的块——很大。然后,在用户空间中,该进程可以自由地按照自己的喜好切割这些页面。
malloc
起两个作用:
-
从OS请求页面
-
将这些页面划分为已分配的块
所以我打赌发生的事情是你在你拥有的页面的其他地方登陆,而不是在你分配的块中。就操作系统而言,这是可以的
操作系统以页为单位为应用程序分配内存(通常为4 KB)。为了提高效率,可以使用巨大的页面(例如2 MB)
第一个页0永远不会被分配,如果你试图访问它,你会得到一个分段错误。例如,在大多数系统中,访问0 - 4095之间的任何指针都会导致段错误。
然而,一旦一个页面被分配给您,您可以读写该页的任何部分,而不会出现分段错误。(代码页通常不允许写)
当您使用malloc时,它确保您需要的页面在那里。然而,你可以访问你所拥有的记忆,并改变任何你喜欢的方式。(假设你知道那是多少)
一般来说,这比有用更危险,但它可以帮助解释为什么以无效的方式访问内存并不能保证分段错误。
注意:malloc有一个小的结构,例如8字节,在块本身之前的每个分配的内存块的开始,如果你破坏了这个,那么malloc
和free
将无法正常工作。
写入不属于自己的内存并不一定会导致分段错误。
这是当你覆盖其他指针,然后试图访问这些指针导致分割错误。这就是为什么这些错误通常很难调试。
这是典型的堆损坏错误。它可能会不会崩溃,这取决于你有多幸运。
你正在覆盖堆中最有可能不被使用的部分,或者正在以一种不致命的方式破坏堆。