以指针传递结构体给函数时,如何正确访问结构体中的指针变量?
问题根源:未初始化的指针与柔性数组的错误使用
你的段错误完全是因为未初始化的指针访问和柔性数组的错误使用导致的,咱们一步步拆解问题:
1. var指针的野访问问题
不管是在main里直接写p.var[0] = 3.7,还是在fun里用(*inp).var[0] = 4.5,本质都是在操作一个未初始化的野指针。double* var只是一个指针变量,它本身不持有任何可写的内存空间——你必须先给它分配一块能存放double值的内存,才能用下标或者解引用操作它。
你提供的第二个"可正常运行"的代码其实也存在同样的问题,它能运行纯属运气(属于C语言里的未定义行为),换个编译器或操作系统大概率也会触发段错误。
2. 柔性数组arr[]的错误使用
结构体里的int arr[]是C语言的柔性数组成员,它有两个关键特性:
- 结构体本身的大小不包含这个数组的空间(你可以打印
sizeof(struct prog)看看,只会计算double*、char*的大小加上内存对齐的字节,不会算arr的空间) - 使用柔性数组时,必须手动给结构体分配足够的内存,要包含结构体本身的大小加上柔性数组需要的元素空间
你直接声明struct prog p;然后用p.arr[1] = 32,这是在访问结构体内存之外的随机栈内存区域,同样属于未定义行为,可能破坏栈上的其他数据,甚至触发崩溃。
修复后的代码示例
下面是修正后的代码,彻底解决了这两个问题:
#include<stdio.h> #include<stdlib.h> // 必须包含malloc/free的头文件 struct prog { double* var; char* name; int arr[]; // 柔性数组成员 }; typedef struct prog p; void fun(p *inp); int main() { // 给包含柔性数组的结构体分配内存:结构体基础大小 + 2个int的空间 p *inptr = malloc(sizeof(p) + 2 * sizeof(int)); if (inptr == NULL) { // 务必检查malloc是否成功 perror("malloc for struct failed"); return 1; } // 给var指针分配内存:存放1个double的空间 inptr->var = malloc(sizeof(double)); if (inptr->var == NULL) { perror("malloc for var failed"); free(inptr); // 分配失败时要释放已分配的内存,避免泄漏 return 1; } inptr->arr[1] = 32; fun(inptr); printf("Value var is: %f\n", inptr->var[0]); printf("Value arr[0] is: %d\n", inptr->arr[0]); printf("Value arr[1] is: %d\n", inptr->arr[1]); printf("Name of prog is: %s\n", inptr->name); // 程序结束前释放所有动态分配的内存 free(inptr->var); free(inptr); return 0; } void fun(p *inp) { inp->var[0] = 4.5; // 现在var指向合法的可写内存 inp->arr[0] = 11; inp->arr[1] = 55; inp->name = "User"; // 字符串字面量是只读内存,这里赋值没问题 }
关键修复点说明
- 给柔性数组结构体分配内存时,要计算
结构体基础大小 + 数组元素个数 * 单个元素大小 - 给
var指针分配足够的内存,确保它指向一块合法的、可写的内存区域 - 每次调用
malloc后都检查返回值,避免分配失败导致的后续错误 - 程序结束前释放所有动态分配的内存,防止内存泄漏
内容的提问来源于stack exchange,提问作者rupak rokade
相关产品推荐
相关产品推荐

