天道酬勤,学无止境

使用data.table的R中C堆栈溢出的段错误(segfault from C stack overflow in R using data.table)

问题

我在 R 中使用 data.table 包来读取大型数据框(65046 行,101959 列)。 fread 正在为我工​​作,用于较小的数据帧。 当我尝试读取感兴趣的数据帧时,出现以下错误:

dat <- fread("input_file")
Error: segfault from C stack overflow

R会话信息如下:

R version 3.0.2 (2013-09-25)
Platform: x86_64-unknown-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US       LC_NUMERIC=C         LC_TIME=en_US       
 [4] LC_COLLATE=en_US     LC_MONETARY=en_US    LC_MESSAGES=en_US   
 [7] LC_PAPER=en_US       LC_NAME=C            LC_ADDRESS=C        
[10] LC_TELEPHONE=C       LC_MEASUREMENT=en_US LC_IDENTIFICATION=C 

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] data.table_1.9.4

loaded via a namespace (and not attached):
[1] chron_2.3-45  plyr_1.8.1    Rcpp_0.11.3   reshape2_1.4  stringr_0.6.2

我发现这个问题报告了 1.8.9 版的类似错误,但我运行的是 1.9.4 版,所以我不确定如何解决这个问题。

标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 缓冲区溢出在gdb中有效,但并非没有(Buffer overflow works in gdb but not without it)
    问题 我使用的是32位的CentOS 6.4,并且正在尝试导致程序中的缓冲区溢出。 在GDB中,它可以工作。 这是输出: [root@localhost bufferoverflow]# gdb stack GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>
  • 分段错误和堆栈溢出之间有什么区别?(What is the difference between a segmentation fault and a stack overflow?)
    问题 例如,当我们说一个递归函数时,连续的调用被存储在堆栈中。 但是,由于错误(如果无限进行),该错误是“分段错误”(如GCC所示)。 难道不是“堆栈溢出”吗? 两者之间的基本区别是什么? 顺便说一句,一种解释将比维基百科链接更有用(通过该链接,但对特定查询没有答案)。 回答1 堆栈溢出是[a]原因,结果是分段错误。 至少在x86和ARM上,“堆栈”是一块保留的内存,用于放置局部变量和函数调用的返回地址。 当堆栈用尽时,将访问保留区之外的存储器。 但是该应用程序没有要求内核提供此内存,因此将生成一个SegFault来进行内存保护。 回答2 调用堆栈正在溢出,但是溢出的结果是最终将与调用相关的值压入不属于堆栈的内存中,然后SIGSEGV ! 回答3 现代处理器使用内存管理器来保护进程彼此之间。 x86内存管理器具有许多传统功能,其中之一就是分段。 分段旨在防止程序以某些方式操纵内存。 例如,一个段可能被标记为只读,而代码将被放置在其中,而另一段则是可读写的,这就是您的数据去向。 在堆栈溢出期间,您耗尽了分配给一个段的所有空间,然后您的程序开始写入内存管理器不允许的段中,然后您遇到了段错误。 回答4 堆栈溢出可以表现为显式堆栈溢出异常(取决于编译器和体系结构),也可以表现为分段错误,即无效的内存访问。 最终,堆栈溢出是堆栈空间用完的结果
  • 使用 setrlimit() 设置堆栈大小并引发堆栈溢出/段错误(Set stack size with setrlimit() and provoke a stack overflow/segfault)
    问题 在下面给出的示例中,我尝试将堆栈大小设置为 1kb。 为什么现在可以在foo()在堆栈上分配大小为8kb的整数数组? #include <stdio.h> #include <sys/resource.h> void foo(void); int main() { struct rlimit lim = {1024, 1024}; if (setrlimit(RLIMIT_STACK, &lim) == -1) return 1; foo(); return 0; } void foo() { unsigned ints[2048]; printf("foo: %u\n", ints[2047]=42); } 回答1 该限制会立即设置,但仅在尝试分配新堆栈或尝试增加现有堆栈时进行检查。 内核源代码上的 RLIMIT_STACK(或 LXR 标识符搜索)的 grep 应该告诉。 显然,堆栈的初始大小是文件名 + env 字符串 + arg 字符串以及在setup_arg_pages分配的一些额外页面(2.6.33 1,2 中的 20 页,2.6.34 3 中的 128 Kb)所需的任何大小。 总之: initial stack size = MIN(size for filename + arg strings + env strings + extra pages, MAX
  • data.table 错误,导致 R 中的段错误(data.table bug, causing a segfault in R)
    问题 以下代码使我的R 2.15.0 data.table 1.8.9 ,运行data.table 1.8.9 。 library(data.table) d = data.table(date = c(1,2,3,4,5), value = c(1,2,3,4,5)) # works as expected d[-5][, mean(value), by = list(I(as.integer((date+1)/2)))] # crashes R d[-5, mean(value), by = list(I(as.integer((date+1)/2)))] 在相关说明中,以下两个命令具有非常不同的输出: d[-5][, value, by = list(I(as.integer((date+1)/2)))] # I value # 1: 1 1 # 2: 1 2 # 3: 2 3 # 4: 2 4 d[-5, value, by = list(I(as.integer((date+1)/2)))] # I value # 1: 1 2.121996e-314 # 2: 1 2.470328e-323 # 3: 2 3.920509e-316 # 4: 2 2.470328e-323 更简单的命令使我的R从评论中崩溃: d[-5, value, by = date]
  • 为什么在声明堆栈中的大型数组时在C中出现段错误?(Why do I get a segfault in C from declaring a large array on the stack?)
    问题 我从以下代码行中遇到了段错误: int fatblob[1820][286][5]; 这是为什么? 回答1 您尝试分配1820 * 285 * 5 * sizeof(int)字节=大约10MB(如果sizeof(int) == 4 )。 默认情况下,这可能比操作系统为堆栈分配的字节数更多,因此您会遇到堆栈溢出/段错误。 您可以通过在创建线程时要求额外的堆栈,在堆上分配或更改OS默认值来解决此问题。 回答2 因为您的堆栈段较小,所以1820*285*5 int s。 通常在1MB附近。 回答3 因为堆栈溢出。 尝试在堆上分配该数组。 回答4 int fatblob[1820][286][5]; 您尝试分配的内存位置为180 * 286 * 5 * 4(让int的大小= 4),大约为9.8 MB,因此有可能在您的OS上使用较小的默认堆栈大小。 LINUX的堆栈大小为8192 KB(即8 MB)。 因此,很显然,如果您试图在堆栈上分配更多的内存,将会导致堆栈溢出。 您可以尝试更改操作系统的堆栈大小。 在LINUX中,您可以尝试ulimit ulimit -s <您想要的大小> 喜欢 $ ulimit -s 1024 希望对您有帮助。 回答5 C中的自动变量(默认类型)通常在堆栈上分配。 堆栈是为每个线程分配的内存区域,尽管它在许多操作系统上可能会增长,但始终具有有限的大小。
  • 查找分段故障原因的方法是什么?(What's your method for finding the cause of a segfault?)
    问题 或只是一般的调试,您喜欢如何查找代码中的错误。 专门针对C / C ++,但一般来说是所有语言。 我一直在尝试寻找造成这种令人讨厌的段错误的原因,但我想面对的挑战是自己找到它,而不是在线发布。 您对像我这样的padawan有什么建议吗? 回答1 使用调试器(例如gdb),并在seg故障时打印回跟踪。 它会显示崩溃的行号和文件。 以此为起点。 为了更进一步,您可以重复此过程以确保它不是由于其他错误而导致的随机错误,而不是其他错误,而是该行号上的特定问题。 对于静态代码分析,您可以使用诸如klockworks或lint之类的工具,这些工具会显示代码中可能存在的问题。 对于动态分析,请使用诸如memwatch之类的工具,这些工具将在运行时监视您的内存分配。 我没有指出valgrind,因为它已经被其他人提及,并且无疑是一个很好的工具。 回答2 用GCC的调试闪存进行编译用您的exe启动gdb r(如果需要,则带有参数) bt 此解决方案通常可以确定段错误及其原因。 回答3 尝试将您的代码放入糟糕的情况。 如果您正在编写解析器,请向其抛出BMP,JPG,随机文本,然后看看会发生什么。 如果您正在编写RPC协议服务器,请使用大量并发请求将其过载,在其中写入垃圾内容,在任何地方都断开与客户端的连接... 开始时不要微妙,抛出任何可能,然后尝试欺骗您的代码。 回答4 我通常在调试器中运行
  • C ++程序中的堆栈溢出错误(stack overflow error in C++ program)
    问题 所以我有这个复杂的类,我想有一个二维复数数组,这是代码的一部分,而不是全部代码 class Complex { public: /* construction/destruction */ Complex(double r, double i) { this->r = r; this->i = i; } Complex() { r=0.0; i=0.0; } ~Complex() { r=0.0; i=0.0; } /* operations */ Complex operator+(Complex &c) { return Complex( r+c.r, i+c.i ); } double r, i; }; int main() { const int HEIGHT = 256; const int WIDTH = 256; Complex G[HEIGHT][WIDTH]; } 所以这行Complex G [HEIGHT] [WIDTH]; 是导致问题的原因,知道为什么吗? 回答1 Visual Studio的默认堆栈大小为1MB,如下所示: Complex G[HEIGHT][WIDTH]; 大约只有1MB,您可以使用/ F修改此文件,并说(强调我的): 如果没有此选项,则堆栈大小默认为1 MB 。 number参数可以采用十进制或C语言表示法。
  • 递归main()-为什么会出现段错误?(Recursive main() - why does it segfault?)
    问题 为什么下面的程序出现段错误? int main() { main(); } 即使这是一个不会结束的递归,因此从定义上来说是无效的,但我不明白为什么会出现segfaults(gcc 4.4.3和clang 1.5(trunk))。 回答1 因为每次调用它自己时,它都会分配一点堆栈空间。 最终,它耗尽了堆栈空间和段错误。 不过,我很惊讶它带有段错误。 我本来希望(鼓卷)堆栈溢出! 回答2 您会得到堆栈溢出(!) 回答3 int main() { main(); } 会导致堆栈溢出。 但, 像这样的优化版本(不是调试模式): int main() { return main(); } 将以尾递归调用(也称为无限循环)转换递归! 回答4 它是递归的,没有基本情况,这会导致堆栈溢出 回答5 这会导致堆栈溢出,这被诊断为系统上的段错误。 回答6 每个函数调用都会在堆栈中添加整个对象,并且在函数退出时,这些条目将从堆栈中删除。 这里我们有没有退出条件的递归函数调用。 因此,它有无数个函数依次调用,并且此函数永远不会退出,并且整个函数永远不会从堆栈中删除,这将导致堆栈溢出。
  • 如何解决R Studio中的“保护堆栈溢出”问题(How to solve 'protection stack overflow' issue in R Studio)
    问题 我正在尝试使用glmnet软件包构建模型,但是在运行以下行时出现以下错误: #library('glmnet') x = model.matrix(response ~ ., data = acgh_frame[,c(3:ncol(acgh_frame))]) Error: protect(): protection stack overflow 我知道这是由于我在数据框中存在大量变量(26​​k +)所致。 当我使用较少的变量时,错误不会显示。 我知道如何在命令行R中解决此问题,但是我需要留在R Studio中,因此我想从R Studio中对其进行修复。 那么,我该怎么做呢? 回答1 @ An鱼 您可以将ppsize指定为Rstudio的命令行参数 rstudio.exe --max-ppsize=5000000 您也可以通过.Rprofile或在运行时使用options(expressions = 5e5)命令来设置表达式选项。 > options(expressions = 5e5) >?options ... 表达式: 对将要计算的嵌套表达式的数量设置一个限制。 有效值为25 ... 500000,默认值为5000。如果增加该值,则可能还希望使用更大的保护堆栈来启动R;否则,可能会增加R。 请参阅内存中的--max-ppsize。 还要注意
  • unixODBC (DB2) + PHP + CentOS 的段错误(segfault with unixODBC (DB2) + PHP + CentOS)
    问题 经过 2 天的战斗,我尝试在这里寻求帮助。 我正在使用 unixODBC (2.2.11) 在 CentOS 5.4 服务器上处理 DB2 (iSeries) 和 PHP (5.3)。 我猜是自从 PHP 从 5.1 升级到 5.3 以来,我让 PHP 在某些查询上出现段错误。 经过一番调查,我发现问题出现在一些带有长字符字段的查询中,例如这个表: TABLE ( CONTRACTID NUMERIC, SOMETEXT CHAR(583) ) 这段简单的代码引发了段错误: try { $conn = new PDO("odbc:".$dsn, $username, $password, array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION) ); } catch (Exception $e) { echo $e->getMessage(); } $sql = 'SELECT * FROM LIB.TABLE '; $stmt = $conn->prepare($sql); $vals = $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); unixODBC 和/或 PHP >= 5.1 是否有任何列长度限制或错误? 这个网络应用程序运行得非常好
  • 是否正在访问其绑定的未定义行为之外的全局数组?(Is accessing a global array outside its bound undefined behavior?)
    问题 今天我刚刚在班上做了一次考试---读取C代码和输入,并且所需的答案是如果程序实际运行将在屏幕上显示。 将a[4][4]为全局变量的问题之一,并且在该程序的某个点,它尝试访问a[27][27] ,因此我回答了类似的问题,即“访问超出其边界的数组是一个未定义的行为”,但老师说a[27][27]的值为0 。 之后,我尝试了一些代码来检查“所有未初始化的golbal变量都设置为0 ”是否正确。 好吧,这似乎是真的。 所以现在我的问题是: 似乎已清除并保留了一些额外的内存以供代码运行。 保留多少内存? 为什么编译器保留的内存比应有的多,它的用途是什么? 在所有环境中a[27][27]是否都为0 ? 编辑 : 在该代码中, a[4][4]是唯一声明的全局变量,并且main()中还有更多局部变量。 我在DevC ++中再次尝试了该代码。 它们都是0 。 但这在VSE中是不正确的,在VSE中,大多数值为0但有些具有随机值,正如Vyktor指出的那样。 回答1 您是对的:这是未定义的行为,您不能算出它总是产生0 。 至于为什么在这种情况下看到零的原因:现代操作系统将内存分配给进程中相对较粗的块(称为页面),这些块比单个变量大得多(在x86上至少为4KB)。 当您有一个全局变量时,它将位于页面上的某个位置。 假设a是int[][]类型,并且int s是系统上的四个字节,则a[27][27
  • 什么会导致 Java 本机函数(在 C 中)在进入时出现段错误?(What can cause a Java native function (in C) to segfault upon entry?)
    问题 该项目 我正在使用 Java 本机接口为内部网络和网络测试工具的 C 库编写 Java 命令行接口。 C 代码(不是我写的)复杂且低级,通常在位级别操作内存,并且专门使用原始套接字。 该应用程序从 C 端(在后台运行的 pthreads)和 Java 端(ScheduledThreadPoolExecutors 运行调用本机代码的线程)是多线程的。 也就是说,C 库应该大部分是稳定的。 事实证明,Java 和 JNI 接口代码导致了问题。 问题 应用程序在进入本机 C 函数时因分段错误而崩溃。 这仅在程序处于特定状态时发生(即成功运行特定本机函数导致对另一个特定本机函数的下一次调用发生段错误)。 此外,当发出quit命令时,应用程序会因类似的段错误而崩溃,但同样,只有在成功运行相同的特定本机函数后才会崩溃。 我是一个没有经验的 C 开发人员和一个有经验的 Java 开发人员——我习惯于崩溃给我一个特定的原因和一个特定的行号。 在这种情况下,我所hs_err_pid*.log就是hs_err_pid*.log输出和核心转储。 我已经在这个问题的末尾包括了我能做的。 我目前的工作 自然,我想找到发生崩溃的特定代码行。 我在 Java 端的本机调用之前放置了一个System.out.println()和一个printf()作为本机函数的第一行
  • Heartbleed 错误是 C 中经典缓冲区溢出漏洞的表现吗?(Is the heartbleed bug a manifestation of the classic buffer overflow exploit in C?)
    问题 在我们关于安全的第一个 CS 讲座中,我们了解了 C 的问题,即不检查所谓的缓冲区长度,以及一些可以利用此漏洞的不同方式的示例。 在这种情况下,看起来这是一个恶意读取操作的案例,其中应用程序只是读取了多少字节的内存 我断言 Heartbleed 错误是 C 缓冲区长度检查问题的表现是否正确? 为什么恶意使用在尝试读取另一个应用程序的内存时不会导致分段错误? 在写入内存(然后从内存中读取)之前简单地将内存归零会导致分段错误吗? 或者这是否因操作系统而异? 还是在其他一些环境因素之间? 显然,无法确定对该漏洞的利用。 那是因为心跳函数在调用时没有记录吗? 否则,对 ~64k 字符串的任何请求都可能是恶意的吗? 回答1 我断言 Heartbleed 错误是 C 缓冲区长度检查问题的表现是否正确? 是的。 Heartbleed 错误是 C 中经典缓冲区溢出漏洞的表现吗? 不。“经典”缓冲区溢出是您将更多数据写入堆栈分配的缓冲区而不是它可以容纳的数据,其中写入的数据由敌对代理提供。 恶意数据溢出缓冲区并覆盖当前方法的返回地址。 当该方法结束时,它返回到一个包含攻击者选择的代码的地址并开始执行它。 相比之下,heartbleed 缺陷不会覆盖缓冲区,也不会执行任意代码,它只会越界读取内存中很可能有敏感数据的代码。 为什么恶意使用在尝试读取另一个应用程序的内存时不会导致分段错误?
  • 如何处理或避免C ++中的堆栈溢出(How to handle or avoid a stack overflow in C++)
    问题 在C ++中,堆栈溢出通常会导致程序无法恢复的崩溃。 对于需要真正强大的程序,这是不可接受的行为,特别是因为堆栈大小有限。 有关如何处理该问题的几个问题。 有没有一种方法可以通过常规技术来防止堆栈溢出。 (一种可扩展的,健壮的解决方案,包括处理占用大量堆栈的外部库等) 有没有一种方法可以解决堆栈溢出的情况? 最好在没有处理程序处理此类问题之前解开堆栈。 有一些语言,它们的线程带有可扩展的堆栈。 在C ++中有可能发生这种情况吗? 有关C ++行为解决方案的任何其他有用评论,将不胜感激。 回答1 处理堆栈溢出不是正确的解决方案,相反,您必须确保程序不会溢出堆栈。 不要在堆栈上分配大变量(“大”取决于程序)。 确保任何递归算法在已知最大深度后终止。 如果递归算法可能递归未知次数或大量次数,则可以自己管理递归(通过维护自己动态分配的堆栈),也可以将递归算法转换为等效的迭代算法 必须“真正强大”的程序将不会使用“占用大量堆栈”的第三方或外部库。 请注意,某些平台会在发生堆栈溢出时通知程序,并允许程序处理错误。 例如,在Windows上,将引发异常。 但是,此异常不是C ++异常,而是异步异常。 C ++异常只能由throw语句throw ,而异步异常则可以在程序执行期间的任何时间引发。 但是,这是预料之中的,因为堆栈随时可能发生溢出:任何函数调用或堆栈分配都可能会使堆栈溢出。
  • 在递归C ++函数中捕获“堆栈溢出”异常(Catching “Stack Overflow” exceptions in recursive C++ functions)
    问题 是否可以在递归C ++函数中捕获stack overflow exception ? 如果是这样,怎么办? 所以在这种情况下会发生什么 void doWork() { try() { doWork(); } catch( ... ) { doWork(); } } 我不是在寻找特定操作系统的答案。 就一般而言 回答1 确实没有便携式方法可以做到这一点。 失控的递归函数通常会在尝试分配超出堆栈地址空间的堆栈帧时导致无效的内存访问。 根据操作系统的不同,这通常只会使您的程序崩溃并出现分段错误/访问冲突。 换句话说,它不会抛出可以由该语言以标准方式处理的c ++异常。 回答2 本身也不例外,但是如果您只想将堆栈使用量限制为固定数量,则可以执行以下操作: #include <stdio.h> // These will be set at the top of main() static char * _topOfStack; static int _maxAllowedStackUsage; int GetCurrentStackSize() { char localVar; int curStackSize = (&localVar)-_topOfStack; if (curStackSize < 0) curStackSize = -curStackSize; // in
  • 什么是细分错误?(What is a segmentation fault?)
    问题 什么是细分错误? 在C和C ++中有区别吗? 分段错误和悬空指针如何关联? 回答1 分段错误是由于访问“不属于您”的内存而引起的一种特定类型的错误。 它是一种帮助机制,可防止您破坏内存并引入难以调试的内存错误。 每当遇到段错误时,您就知道您在内存上做错了–访问已被释放的变量,写入内存的只读部分,等等。在大多数语言中,分段错误在本质上都是相同的,这会让您陷入困境使用内存管理,C和C ++中的段错误之间没有主要区别。 至少在诸如C(++)之类的较低级语言中,有很多方法可以获取段错误。 获取段错误的一种常见方法是取消引用空指针: int *p = NULL; *p = 1; 当您尝试写入标记为只读的一部分内存时,会发生另一个段错误: char *str = "Foo"; // Compiler marks the constant string as read-only *str = 'b'; // Which means this is illegal and results in a segfault 悬空的指针指向不再存在的事物,例如: char *p = NULL; { char c; p = &c; } // Now p is dangling 指针p悬空是因为它指向在块结束后不再存在的字符变量c 。 当您尝试取消引用悬空指针(例如*p='A' )时,可能会遇到段错误。
  • 带有重复符号的 C++ 插件库上的段错误(Segfault on C++ Plugin Library with Duplicate Symbols)
    问题 我有一个跨平台的 C++ 应用程序,它被分成几个共享库并从插件共享库加载附加功能。 插件库应该是自包含和自己运行的,而不知道或依赖于调用应用程序。 其中一个插件包含从主应用程序复制的代码,因此包含与引擎中的符号名称重复的符号名称。 (是的,我知道这通常是一个禁忌,但在编写插件时,引擎是一个整体二进制文件,无法共享库。)在 Windows 上,一切正常。 在 Linux 上,我们遇到了段错误。 通过查看错误的堆栈跟踪,它是在调用重复类名中的函数时在插件中发生的。 这似乎是引擎和插件的共享代码版本略有不同的结果(插件中注释掉了某些类功能)。 就好像插件将它的符号运行时链接到引擎的而不是它自己的。 我们通过将dlopen的参数更改为dlopen(pFilepath, RTLD_LAZY | RTLD_LOCAL)来“修复”该问题。 但是当我们重写引擎以拆分为共享库时(为了在插件中重用的最终目的),我们再次收到段错误错误。 查看堆栈跟踪,它来自引擎 -> 插件 -> 引擎。 有没有办法指定运行时链接器不将插件的符号映射到引擎(特别是如果它们在插件中定义)? 谢谢! 马特 编辑 2009-12-3 我首先尝试将插件的代码包装在它自己的命名空间中。 这不起作用,因为它静态链接到一个也链接到引擎的库。 静态库的版本不同,所以segfault! 然后我改变了引擎的构建,它的库被静态链接。
  • 访问越界内存后不会立即出现分段错误(Segmentation Fault doesn't come up immediately after accessing out-of-bound memory)
    问题 我写了这段代码并且很快就预料到了分段错误,但似乎我被允许访问我不应该访问的内存片段。 #include<stdio.h> int main() { int tab[1]; tab[0]=42; int i; //Expecting Seg Fault from i==1... for(i=0;;i++) { printf("%d \t %d \n", i, tab[i]); } return 0; } 我正在编译使用: gcc -Wall -Wextra my_code.c -o segfault && ./segfault 执行后,变量i在出现分段错误之前达到 1000 阶的值。 我的问题是:为什么到目前为止我可以阅读tab ? PS:使用#include <stdlib.h>并声明int * tab = (int*)malloc(sizeof(int)); 什么都改变不了... 谢谢,最好。 回答1 您的数组tab将位于堆栈上的某个位置。 当您打印超过数组的末尾时,您实际上是在打印堆栈上其他内存位置的值。 需要大约 1000 次迭代才能获得 seg 错误的原因是堆栈是按页映射的,而页的大小通常为 4 KB。 一旦你读取了大约 1000 个整数,你就超过了你应该到达的位置大约 4000 个字节,并且你已经越过一个未映射的页面。 从未映射的页面读取是实际触发段错误的原因。
  • 从内核 (3.7) 模块读取 block_device:submit_bio 中的段错误,缺少 bd_disk(Reading block_device from kernel (3.7) module: segfault in submit_bio, bd_disk is missing)
    问题 你好堆栈溢出。 想知道我在尝试直接从内核模块访问块设备时出了什么问题。 (amd64 上的内核 3.7) 我使用 get_gendisk() 获取设备的 (struct gendisk*)。 接下来,使用 bio_map_kern() 创建一个 bio,使用 bdget_disk() 将 block_device 添加到其中,并使用 submit_bio() 发送它。 (见下面的代码) 在“sdb”上执行此操作时,它工作正常。 在 'loop0' 或 ramdisk 设备上执行此操作时,它会因段错误而失败。 故障归结为 generic_make_request_checks() 调用内联函数 bdev_get_queue(),它试图访问 block_device 结构中的“bd_disk”字段。 RIP: 0010:[] [] generic_make_request_checks+0x3e/0x2b1 当从 'sdb' 获取 block_device 时,bd_disk 被链接回设备的 gendisk 结构(在它的任何分区上)。 在“loop0”设备上尝试相同操作时,该指针为零。 但是 loop0 已正确设置,因为我可以使用它进行 mkfs、mount 或 dd。 有关如何设置简单数据读取的任何提示? 清洁和正确的方法? 将 gendisk 指针添加到 block
  • 如何在AC / C ++程序中检测可能的/潜在的堆栈溢出问题?(How to detect possible / potential stack overflow problems in a c / c++ program?)
    问题 有没有一种标准的方法来查看您的应用程序有多少堆栈空间,以及在运行期间堆栈使用率最高的水印是多少? 在可怕的实际溢出情况下还会发生什么? 它会崩溃,触发异常或发出信号吗? 在所有系统和编译器上是否存在标准或不同? 我正在专门针对Windows,Linux和Macintosh。 回答1 在Windows上,将生成堆栈溢出异常。 以下Windows代码说明了这一点: #include <stdio.h> #include <windows.h> void StackOverFlow() { CONTEXT context; // we are interested control registers context.ContextFlags = CONTEXT_CONTROL; // get the details GetThreadContext(GetCurrentThread(), &context); // print the stack pointer printf("Esp: %X\n", context.Esp); // this will eventually overflow the stack StackOverFlow(); } DWORD ExceptionFilter(EXCEPTION_POINTERS *pointers, DWORD