栈和堆的区别
请告诉我关于下面代码的堆栈和堆之间的区别
int main()
{
int arr[3];
int *a;
arr [5] = 6; // out of bound but it will not give error.
arr [3000] = 8 ; //SIGSEGV
a = malloc (sizeof (int));
a[4] = 6;
a[4000] = 8; //No error
}
我知道 arr 是一个静态数组,当我执行 arr[3000] 时,我正在访问其他进程的地址,这会给出 SIGSEGV 错误。但我不明白为什么 a[4000] 不会给我任何运行时错误,即 SIGSEGV 信号。
谢谢
Please tell me the difference between stack and heap with respect to below code
int main()
{
int arr[3];
int *a;
arr [5] = 6; // out of bound but it will not give error.
arr [3000] = 8 ; //SIGSEGV
a = malloc (sizeof (int));
a[4] = 6;
a[4000] = 8; //No error
}
I know that arr is a static array and I am accessing some other process's address when I do arr[3000] which gives SIGSEGV error. But I don't understand why a[4000] will not give me any run time error i.e., SIGSEGV signal.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不能保证这些调用中的任何一个实际上都会写入无法访问的内存(这会触发段错误)。程序很可能有权写入该内存并且不会触发段错误,但会覆盖与数组无关的其他一些内部数据。这当然可能会导致程序其他地方出现意想不到的效果。
一般来说,这称为未定义行为。没有承诺当你写出数组的边界时会发生什么,任何事情都可能发生也可能不会发生。
It's not guaranteed that any of those calls actually write to inaccessible memory (which would trigger a segfault). It's just as likely that the program has permission to write to that memory and doesn't trigger a segfault, but overwrites some other internal data unrelated to your array. This of course might lead to unexpected effects elsewhere in the program.
Generally this is called undefined behavior. There are no promises made what happens when you write out of the bounds of the array, anything might or might not happen.
引用数组边界之外的项是未定义的行为,这意味着任何事情都可能发生(例外、无例外或其他)。 arr[5] 赋值没有导致错误的原因可能是因为该值仍在有效的堆栈空间内(但它可能会导致稍后在运行时间较长的应用程序中出现错误)。对已分配数组的无效分配可能会导致写入属于该进程的内存中的页面,因此不会导致错误。但每次运行情况可能会有所不同。即使该地址属于进程地址空间之外的页面,它也取决于操作系统实际发生的情况。
Referencing the items outside the array bounds is undefined behavior, which means anything could happen (exception, no exception, or other). The reason the
arr[5]
assignment did not cause an error is probably because the value was still inside valid stack space (but it could result in errors later on in a longer running application). The invalid assignment to the allocated array may have resulted in a write to a page in memory belonging to the process and thus not result in an error. But that could change from run to run. And even if the address belonged to a page outside the process' address space, it depends on the OS on what will actually happen.堆是您 malloc() 内存块的内存。
a[4000] = 8;没有失败,因为幸运的是它没有落入其他进程的内存地址。这只是一个偶然
Heap is the memory from which you malloc() the block of memory from.
a[4000] = 8; didn't fail because it was a luck that it didn't fall into memory address of other process. It was just by chance
您突出显示的所有情况都代表“未定义的行为”。
在某些情况下,这是一个空操作,而在其他情况下,这是一个分段错误。
“未定义行为”的特别糟糕之处在于,它可能会按预期工作一段时间,但随后突然开始产生“不良副作用”(即分段错误)。这使得在生产中调试和重现这些条件变得非常困难。
All cases that you highlighted represent 'undefined behavior'.
And in some cases it's a noop, and in others it's a segmentation fault.
What's particularly bad about 'undefined behavior' is that it may work as expected for some time, but then suddenly start producing "undesirable side effects" ( i.e. segmentation faults ). This makes it very difficult to debug and reproduce these conditions in production.
它将在另一个平台或架构上。这其实并不重要——你必须始终避免 UB。
无论如何,区别在于系统分配器的实现(假设编译器没有将 malloc 的结果放在堆栈上)。
你的分配器如何管理和分配内存是一个你不应该依赖的实现细节,特别是当你扔掉 UB 时。
分配器可以从更大的物理分配中出售内存块。此底层实现因平台而异。
It will on another platform or architecture. This really doesn't matter - you must always avoid UB.
At any rate, the difference is in the implementation of your system's allocator (assuming the compiler did not place the result of malloc on the stack).
How your allocator manages and distributes memory is an implementation detail you should not rely on, especially when you're throwing UB around.
An allocator can vend pieces of memory from a larger physical allocation. This underlying implementation varies by platform.
缓冲区溢出是未定义的行为。如果缓冲区溢出在堆栈上,则周一可能会崩溃;如果在堆上,则周二可能会崩溃。它们只是未定义的行为。
这是 C 段落,表示这是未定义的行为:
当然
[]
是一个伪装的一元*
运算符:Buffer overflows are undefined behavior. A buffer overflow can crash on Monday if it is on stack and crash on Tuedsay if it is on heap. They are just undefined behavior.
Here is the C paragraph that says it is undefined behavior:
And of course a
[]
is a disguised unary*
operator: