为何C语言栈代码用->操作符和指针无法运行,换.操作符可正常运行
问题原因
指针版本运行异常的核心原因是野指针访问:
你定义struct stack *s时,只创建了一个指针类型的变量,没有为这个指针分配它所指向的struct stack类型的实际内存空间,此时s里存的是内存里的随机垃圾地址,属于野指针。后续直接用s->size、s->top这类写法,本质是往随机的非法内存地址写数据,会触发段错误等运行时异常。
而你注释掉的结构体实例版本struct stack s;是直接在程序栈空间上为整个结构体分配了内存,s本身就是实际存在的结构体变量,用.操作成员是完全合法的,所以可以正常运行。
错误代码位置
出问题的就是main函数里指针初始化的前几行:
struct stack * s; // 仅声明指针,未指向合法内存,是野指针 s->size = 80; // 这一步就已经触发非法内存访问,属于未定义行为 s->top = -1; s->arr = (int*)malloc(s->size * sizeof(int));
修复方法
在操作s的成员之前,先为struct stack结构体本身分配堆内存,让s指向合法的内存空间,再进行后续成员赋值即可。修复后的完整main函数代码如下:
int main() { // 先为结构体本身分配内存,让s指向合法的堆空间 struct stack * s = (struct stack*)malloc(sizeof(struct stack)); s->size = 80; s->top = -1; s->arr = (int*)malloc(s->size * sizeof(int)); // 手动压入第一个元素 s->arr[0] = 7; s->top++; // 判空检查 if (isEmpty(s)) { printf("The stack is empty."); } else { printf("The stack is not empty."); } // 判满检查 if (isFull(s)) { printf("The stack is full."); } else { printf("The stack is not full."); } // 动态申请的内存使用完需要手动释放,避免内存泄漏 free(s->arr); free(s); return 0; }
补充说明
->操作符的本质是对指针解引用后访问成员,等价于(*指针变量).成员名,使用的前提是指针必须指向合法、已分配的对应类型内存,否则就会出现非法访问问题。- 不需要把结构体定义成指针才能传给接收结构体指针参数的函数,原来的结构体实例版本,传参时传入
&s取结构体的地址即可,效果和结构体指针传参完全一致。 - 你注释中写的
new int[s.size]是C++的动态内存申请语法,纯C环境不支持new关键字,动态内存分配要使用malloc/calloc这类标准库函数。
内容的提问来源于stack exchange,提问作者Rishujeet Rai
相关产品推荐
相关产品推荐

