char*未初始化引发段错误,为何教授的相似代码可正常运行?
你的段错误原因与教授代码的安全逻辑解析
一、你的代码触发Segmentation Fault的根本原因
你声明了char *str但没有初始化,这意味着str是一个野指针——它指向内存中的随机位置,这个位置可能是程序无权访问的区域,或者存储的不是合法的C字符串(缺少\0终止符)。
在你的循环逻辑里,第一次进入for(j = 0; j < R; j++)时,直接执行了:
if(strcmp(mat[j][trace[j]], str) < 0 )
strcmp函数要求两个参数都是指向合法C字符串的有效指针,而此时str是未初始化的野指针,当strcmp尝试读取它指向的内存时,就会触发段错误(非法内存访问/内存越界)。
简单来说:你在使用str之前,从来没有给它赋值过有效的字符串地址,直接拿它去和其他字符串比较,这必然会出问题。
二、教授的代码为什么能正常运行
教授的代码里虽然也声明了char *min_word未初始化,但他的判断条件利用了逻辑或的短路求值特性:
if ((min_idx==-1) || (strcmp(matrix[j][idx[j]], min_word)<0))
逻辑或||的规则是:如果第一个条件为真,就不会执行后面的条件判断。
具体执行流程:
- 每次进入外层
while循环时,min_idx被初始化为-1。 - 第一次遍历
j时,min_idx==-1为真,所以后面的strcmp根本不会执行,直接进入代码块:
这一步就给min_idx = j; min_word = matrix[min_idx][idx[min_idx]];min_word赋值了一个有效的字符串指针,完成了初始化。 - 在后续的
j遍历以及后续的while循环中,min_idx已经不是-1了,此时min_word已经指向了一个合法的C字符串,所以strcmp的调用是安全的。
换句话说,教授的代码通过逻辑短路,确保了strcmp被调用时,min_word一定已经被赋值过有效的指针,不会出现野指针访问的情况。
修复你的代码的建议
你可以参考教授的逻辑,调整判断条件,确保str在被strcmp使用前已经被初始化:
while(i < (R*C)) { // 初始化min为无效值,str先置为NULL int min = -1; str = NULL; for(j = 0; j < R; j++) { if(trace[j] < C) { // 第一次时min为-1,直接赋值;之后用str比较 if(min == -1 || strcmp(mat[j][trace[j]], str) < 0 ) { str = mat[j][trace[j]]; min = j; } } } tmp[i++] = mat[min][trace[min]]; trace[min]++; }
这样就能避免野指针导致的段错误了。
内容的提问来源于stack exchange,提问作者AXE47
相关产品推荐
相关产品推荐

