我只是想知道当我使用非分配空间时编译器不会抛出exception,这里是一个代码例如:
#include #include int main() { int i, n; int *a; printf("Number of elements to be entered:"); scanf("%d",&n); a = (int*)calloc(n, sizeof(int)); printf("Enter %d numbers:n",n); for( i=0 ; i < n ; i++ ) { scanf("%d",&a[i]); } printf("The numbers entered are: "); for( i=0 ; i < n ; i++ ) { printf("%d ",a[i]); } free( a ); return(0); }
如果n = 3例如我静静地说:
a[10]=3;
它会工作,不会抛出exception,我可以打印它,那么使用一个元素出界的影响是什么? 有没有办法知道大小? 因为(sizeof)不会对calloc数组起作用。
你有一些可怕的未定义行为 (UB)。 阅读Lattner的博客,了解每个C程序员应该了解的未定义行为 。
请注意,对于UB,可能会发生非常糟糕的事情,或者说没有什 观察到的行为甚至可能无法从一次运行再到下一次运行(阅读ASLR )。
要解释系统上发生的情况,您需要深入了解实现细节,远低于C或C ++代码。 例如,您可以请求生成的汇编程序(例如,使用gcc -Wall -O -fverbose-asm -S
编译代码并查看生成的*.s
汇编程序文件)。 或者您可以使用(在Linux上)类似strace(1)的东西来理解所涉及的系统调用 。 我想象在Linux上,对calloc
的调用会要求内核至少有一页堆数据(即calloc
会使用mmap(2)或sbrk(2) ….)因为页面是4Kbytes数据,您访问的字节实际上是在您的虚拟地址空间中 。
顺便说一下,我邀请您安装并使用一些Linux发行版 。 由于它主要由自由软件组成 ,因此您可以研究所涉及的源代码(包括您的代码,标准C库和Linux内核,甚至是编译器)。 这可能需要你很多年,但你原则上可以理解所有的实现细节。
阅读乔尔的泄漏抽象定律 ……
有没有办法知道尺寸? (一些堆分配的数据)
不,不是在便携式C中。您应该自己管理尺寸(即有一些方法来了解它)。 一个有用的技巧可能是将其保持在数组数据附近,例如在包含大小的struct
中,并以灵活的数组成员结束。 但你仍然需要一些约定来获得大小。
超出界限访问数据会给您带来未定义的行为,这意味着任何事情都可能发生。
如果远离界限,由于访问未映射或受保护的内存页面,可能会出现分段错误。 但是,这假设您的代码到机器代码的映射有点简单。
事实是,编译器只会让您觉得您的代码直接映射到机器代码。 当你通过引起未定义的行为来破坏规则的那一刻,幻觉可能以一些非常奇怪的方式破坏,这就是未定义的行为。
对不起,您无法知道已分配数组的大小(请参阅: 确定c中动态分配内存的大小 )
访问一个越界数组是否会抛出“exception”取决于数组/ MMU边界的位置。 无论如何,它不是可靠的!
要获得“真实”exception,请切换到C ++,删除calloc
,使用vector::at
。
以上就是c/c++开发分享使用未分配的空间calloc相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/519164.html