结构体指针访问成员值异常问题求助(C语言)
问题根源:数组越界触发未定义行为
嘿,这个问题其实是典型的数组越界导致的诡异问题,我来给你拆解清楚:
首先看你的结构体定义:
typedef struct { uint8_t D[19]; uint32_t *D_ptr[19]; } sys_data;
这里的D和D_ptr都是19个元素的数组,合法的索引范围是0到18(数组索引从0开始,19个元素的话最大索引是18)。
但你的两个for循环都写了i < 20,这意味着循环会执行20次,i会取到0到19的值——当i=19时,你已经在访问数组的越界位置了!
越界访问带来的具体影响
C语言不会自动做数组边界检查,所以越界操作会直接修改不属于结构体的内存区域,进而引发各种奇怪的问题:
- 当你执行
S_data.D[19] = 0;时,你修改的是D数组之后的内存,而这块内存正好是D_ptr数组的起始位置(因为结构体成员是连续存储的)。这相当于你在悄悄破坏D_ptr数组里的指针值! - 后续你给
S_data.D_ptr[19]赋值时,同样是在写结构体之外的内存,进一步扰乱了内存布局。
这就解释了为什么直接访问S_data.D[i]能得到正确值(因为D[17]、D[18]本身是合法的,你确实给它们赋了0),但通过D_ptr[i]访问就出问题——因为D_ptr数组的部分指针已经被越界操作破坏了。
快速修复方案
把两个循环的终止条件从i < 20改成i < 19,确保只访问数组的合法索引:
// 修正后的初始化循环 for (i = 0; i < 19; i++) { S_data.D[i] = 0; console("%d",S_data.D[i]); S_data.D_ptr[i] = &S_data.D[i]; } // 修正后的打印循环 for (i = 0; i < 19; i++) { console("Value of var[%d] = %d\n", i, *S_data.D_ptr[i] ); console("Address of var[%d] = %u\n", i, S_data.D_ptr[i] ); }
优化建议:避免硬编码数组大小
为了以后不再犯类似的错误,建议用宏定义数组的大小,这样循环条件和数组定义保持一致:
#define SYS_DATA_ARRAY_SIZE 19 typedef struct { uint8_t D[SYS_DATA_ARRAY_SIZE]; uint32_t *D_ptr[SYS_DATA_ARRAY_SIZE]; } sys_data; // 循环中直接使用宏 for (i = 0; i < SYS_DATA_ARRAY_SIZE; i++) { // ... 你的代码 ... }
这样哪怕以后需要调整数组大小,只需要修改宏定义一行代码,不会再出现循环次数和数组大小不匹配的问题。
内容的提问来源于stack exchange,提问作者Akhil Joy
相关产品推荐
相关产品推荐

