数组遍历指针递增时因nullptr检查错误引发Segmentation fault
数组遍历触发Segmentation Fault的修复方案
问题详情
编译命令:
clang++ -Wall -std=c++11 -o replacement.o replacement.cpp && ./replacement.o
运行错误:
zsh: segmentation fault ./replacement.o
原代码:
#include <iostream> int count_occurances(char* p, char x) { int count = 0; // count number of times x occurs in p while (p != nullptr) { if (*p == x) ++count; ++p; } return count; } int main(int argc, const char * argv[]) { // insert code here... char num_array[4] = {'a', 'b', 'b', 'c'}; std::cout << "Running count occurances array" << count_occurances(num_array, 'b') << "done\n" ; return 0; }
错误原因
你定义的num_array是普通字符数组,没有以'\0'(空字符)结尾,而且循环条件while (p != nullptr)完全错误:指针p是数组首地址,递增后只会指向数组后续元素或数组外的内存,永远不会变成nullptr。这导致指针越界访问不属于程序的内存,触发段错误。
修复方案
方案1:用C风格字符串(带终止符)
给数组添加'\0'终止符,同时修改循环条件判断指针指向的内容是否为终止符:
#include <iostream> int count_occurances(char* p, char x) { int count = 0; // 判断当前字符是否为终止符,而非指针是否为nullptr while (*p != '\0') { if (*p == x) ++count; ++p; } return count; } int main(int argc, const char * argv[]) { // 字符串字面量自动添加'\0',也可以手动定义为{'a','b','b','c','\0'} char num_array[] = "abbc"; std::cout << "Running count occurances array: " << count_occurances(num_array, 'b') << " done\n" ; return 0; }
方案2:传递数组长度(更安全)
不依赖终止符,直接把数组长度传给函数,按长度遍历:
#include <iostream> // 新增长度参数 int count_occurances(char* p, char x, int length) { int count = 0; for (int i = 0; i < length; ++i) { if (p[i] == x) ++count; } return count; } int main(int argc, const char * argv[]) { char num_array[4] = {'a', 'b', 'b', 'c'}; // 传递数组长度,用sizeof计算数组元素个数 std::cout << "Running count occurances array: " << count_occurances(num_array, 'b', sizeof(num_array)/sizeof(num_array[0])) << " done\n" ; return 0; }
内容的提问来源于stack exchange,提问作者Valyrian
相关产品推荐
相关产品推荐

