【问题标题】:Causing a seg fault in C | Heap stack virtual memory导致 C 中的段错误 |堆栈虚拟内存
【发布时间】:2017-10-25 23:20:39
【问题描述】:
#include <stdio.h>

int main() {
  char *ptr;

  while(1){ 
    ++ptr; 
    printf("%p\n", ptr); 
  }
  return 0;
}

问题:您的代码应该增加一个指向 堆,1 个字节,重复,直到程序崩溃。

我试图通过迭代堆栈中的所有地址来创建段错误,一次一个字节。但是,代码只是继续运行,不会导致分段错误。我怎么能改变它导致段错误?

【问题讨论】:

  • 你永远不会取消引用指针。如果您想要段错误,只需执行*((int*)0);
  • 即使没有取消引用,它也是未定义的行为,因为ptr 未初始化。
  • 我认为你必须使用malloc() 来使用指向堆的指针。 ptr= malloc()在堆上获取想要的内存位置,然后就可以用ptr指针访问堆了。
  • 我从您的问题中了解到,您要求的是 2 种不同的东西。您可以指向堆并递增它直到它崩溃,或者您可以指向堆栈上的某个位置并递增它直到它崩溃。你要哪一个?
  • 实际上是堆栈和堆

标签: c memory-management heap-memory virtual-memory stack-memory


【解决方案1】:

要获取指向堆栈的指针,请将其设置为局部变量的地址:

int main() {
    int object;
    int *p = &object;

但是,简单地增加指针不会导致分段错误。要获得分段错误,您需要取消引用无效指针。所以循环应该是这样的:

    while(1) {
        ++ptr;
        printf("%p %d\n", ptr, *ptr);
    }

尝试打印*ptr最终会导致错误。

对于堆,您可以类似地执行此操作,但通过调用 malloc() 而不是局部变量的地址来初始化 p

【讨论】:

  • 为什么不能遍历每个地址?不会访问每个地址,设置一个值,最终导致它用完吗?
  • 在虚拟内存系统中,大多数地址没有被映射,或者其中一些地址是受保护的,因为它们是内核的一部分。所以最终你遇到了一个无法访问的块,这就是导致分段违规的原因。
  • 什么设置了 while 循环将运行多少次迭代的值?说它在分段错误之前运行了 500 次,为什么它运行了 500 次而不是 1000 次?
  • 这取决于操作系统和 C 运行时库如何布置进程内存。当您进入第一个未映射的地址页面时,您会收到错误。
  • 看来你需要了解进程内存是如何实现的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-08
  • 2019-08-07
  • 1970-01-01
  • 2020-01-07
  • 2012-12-09
相关资源
最近更新 更多