问题 变量声明导致分段错误


我不明白程序中出现分段错误的原因。 代码可用 这里

在第29行,我宣布一个 PclImage 变量,使用typedef定义,类似于struct数组。 的定义 PclImage 类型如下(来自 SRC / libMyKinect.h 文件):

typedef struct {
    int valid;
    float x;
    float y;
    float z;
    unsigned char blue;
    unsigned char green;
    unsigned char red;
} Point3d;

typedef Point3d PclImage[480][640];

该程序运行良好,但当我宣布第二个 PclImage,一旦启动程序,我就会出现分段错误。

例如,如果在我添加的第一个文件的第30行 PclImage bgPcl; 程序立即崩溃。

谁能帮我?


2629
2017-12-28 16:20


起源



答案:


如果你宣布一个 PclImage 作为局部变量(在堆栈上),由于堆栈溢出,您可能会遇到分段错误。

PclImage 是一个包含307,200个元素的数组,每个元素(可能)大小约为20个字节,因此整个数组的大小约为6MB。堆栈大小不足以包含其中两个数组;它可能甚至不足以包含一个(作为一般规则,在大多数桌面操作系统上通常可以安全地假设您至少有1MB的堆栈空间可用)。

当你有这么大的对象时,你应该动态地分配它们(使用 malloc 和朋友们)或者,如果你不关心重入,那就是静态的。


14
2017-12-28 16:22





我同意James的意见,即在堆栈上分配这些大型数组很可能是原因。但是,每一个 PclImage 每个加起来只有大约6Meg。除非您在有限的内存环境中运行,否则这应该是可行的。我以前在堆栈上分配了更大的数组。甚至在嵌入式系统上。

詹姆斯的建议使用 malloc 可能会解决它(值得一试只是为了验证问题)。但是,我认为在可能的情况下避免动态分配是一个很好的策略。 malloc的可能替代方法是在外部上下文中声明数组,或者增加线程的堆栈大小。默认情况下,用户创建的进程和/或线程通常会分配相当小的堆栈。找到设置的位置并为其提供足够大的堆栈可能是一件相当简单的事情。

例如,如果这是从使用Windows创建的线程运行的 CreateThread() 例程,第二个参数控制堆栈大小。如果你默认使用 0 (正如大多数人所做的那样),它采用默认的堆栈大小。就像我所知,这是“仅”1 MB。


1
2017-12-28 16:34



你大大估计了嵌入式系统中的内存。拥有超过32K的RAM是巨大的。 。 。我从2017年的角度来看。在2010年,感觉16K是我们为RAM扩散的部分可用性。 - iheanyi
@iheanyi - 正如评论中所说,有些设备是内存限制的,但我在这里谈论经验,而不是猜测。当然是ymmv,但这并不意味着每个嵌入式开发人员都在研究像你一样的系统。 - T.E.D.


答案:


如果你宣布一个 PclImage 作为局部变量(在堆栈上),由于堆栈溢出,您可能会遇到分段错误。

PclImage 是一个包含307,200个元素的数组,每个元素(可能)大小约为20个字节,因此整个数组的大小约为6MB。堆栈大小不足以包含其中两个数组;它可能甚至不足以包含一个(作为一般规则,在大多数桌面操作系统上通常可以安全地假设您至少有1MB的堆栈空间可用)。

当你有这么大的对象时,你应该动态地分配它们(使用 malloc 和朋友们)或者,如果你不关心重入,那就是静态的。


14
2017-12-28 16:22





我同意James的意见,即在堆栈上分配这些大型数组很可能是原因。但是,每一个 PclImage 每个加起来只有大约6Meg。除非您在有限的内存环境中运行,否则这应该是可行的。我以前在堆栈上分配了更大的数组。甚至在嵌入式系统上。

詹姆斯的建议使用 malloc 可能会解决它(值得一试只是为了验证问题)。但是,我认为在可能的情况下避免动态分配是一个很好的策略。 malloc的可能替代方法是在外部上下文中声明数组,或者增加线程的堆栈大小。默认情况下,用户创建的进程和/或线程通常会分配相当小的堆栈。找到设置的位置并为其提供足够大的堆栈可能是一件相当简单的事情。

例如,如果这是从使用Windows创建的线程运行的 CreateThread() 例程,第二个参数控制堆栈大小。如果你默认使用 0 (正如大多数人所做的那样),它采用默认的堆栈大小。就像我所知,这是“仅”1 MB。


1
2017-12-28 16:34



你大大估计了嵌入式系统中的内存。拥有超过32K的RAM是巨大的。 。 。我从2017年的角度来看。在2010年,感觉16K是我们为RAM扩散的部分可用性。 - iheanyi
@iheanyi - 正如评论中所说,有些设备是内存限制的,但我在这里谈论经验,而不是猜测。当然是ymmv,但这并不意味着每个嵌入式开发人员都在研究像你一样的系统。 - T.E.D.