在声明数组时初始化数组会导致C代码崩溃,但是如果被循环清零则不会崩溃?

问题描述 投票:1回答:2

最近在我从事的项目中“修复了一个错误,但是到目前为止,没有人能够解释为什么该修复有效。 (这真的可以解决吗?)该代码在实时系统下的内核空间中运行,因此该问题导致系统完全锁定。这也使调试比平常更加困难。

此版本使系统崩溃:

int  dups[EMCMOT_MAX_AXIS] = {0};
char *coords = coordinates;
char coord_letter[] = {'X','Y','Z','A','B','C','U','V','W'};

此版本不会崩溃

int  dups[EMCMOT_MAX_AXIS];
char *coords = coordinates;
char coord_letter[] = {'X','Y','Z','A','B','C','U','V','W'};
int  i;
for (i=0; i<EMCMOT_MAX_AXIS; i++) {dups[i] = 0;}

真正使事情困惑的是,该实验版本也崩溃了

int  dups[EMCMOT_MAX_AXIS] = {0};
char *coords = coordinates;
char coord_letter[] = {'X','Y','Z','A','B','C','U','V','W'};
int  i;
for (i=0; i<EMCMOT_MAX_AXIS; i++) {dups[i] = 0;}

您可以在此处查看提交和周围的代码:https://github.com/LinuxCNC/linuxcnc/commit/ef6f36a16c7789af258d34adf4840d965f4c0b10

c linux kernel-module rtai
2个回答
0
投票

感谢Nate Eldredge设置了编译器资源管理器,并为%xmm0指针设置了0andriy。这看起来确实像编译器对内核代码使用寄存器不安全的问题(或一些紧密相关的问题)。在Godbolt站点上进行实验,我发现-mno-sse2编译器标志与切换到gcc-6的作用类似,以消除该代码中对$ xmm0寄存器的使用。并且,当在实际应用程序编译中将其添加到编译器标志时,它似乎可以解决该问题。为了深入了解[[right解决方案,可能还需要做更多的工作,但是现在我们似乎有了一些很好的指导。


-3
投票
您只为该数组提供了一个初始化程序。这仅初始化了第一个元素。

根据cppreference.com,从标准中提取:

未显式初始化的所有数组元素都与具有静态存储持续时间的对象相同地隐式初始化。

如果未提供初始化程序:

具有自动存储持续时间的对象被初始化为不确定的值(可能是陷阱表示)

“初始化为不确定的值”通常意味着程序将把剩下的内存留在数组的其余部分中,而已在该内存空间中设置了位。如果这些位使对象的状态是元素类型的无效值(“陷阱表示”),则可能导致处理器中出现“陷阱”。

这种表示形式不太可能,因为值是整数,但是您表示您使用的是特殊平台,因此甚至有可能用于整数。

具有整数类型,静态存储持续时间和整数类型的对象被初始化为无符号零。因此,我想推断出您的数组具有自动持续时间。

© www.soinside.com 2019 - 2024. All rights reserved.