比较C字符串与C++字符串引发段错误?问题排查咨询
段错误原因分析及修复方案
咱们来一步步拆解你遇到的段错误问题,核心出在容器越界访问和循环逻辑错误两个方面:
1. 空容器时的越界访问(触发段错误的直接原因)
当你第一次调用add_movie时,names_list是空的,size()返回0:
- 最初的for循环中,
counter <= names_list.size()-1因为size_t是无符号整数类型,0-1会溢出成一个极大的正整数,导致循环疯狂执行,不断访问names_list[counter]——这些位置完全不存在,直接触发内存越界的段错误。 - 修改后的do-while循环,第一次执行时
counter为0,直接访问names_list[0],但此时容器为空,没有第0个元素,同样触发越界访问,引发段错误。
2. 遍历过程中修改容器的逻辑错误
就算容器不为空,你的代码逻辑也存在严重问题:每遍历一个元素,只要当前元素不等于目标name,就直接添加新电影并修改names_list。这会导致:
names_list的size在遍历过程中变大,循环会继续遍历新添加的元素,重复执行添加逻辑,造成重复添加;- 容器在扩容时可能重新分配内存,之前的遍历位置失效,进一步引发内存异常。
正确的实现方案
正确的逻辑应该是先遍历整个容器检查是否存在目标电影,确认不存在后再执行添加操作,代码如下:
void Movies::add_movie(char name[], unsigned short rating, unsigned short watched_times) { // 先遍历所有已存在的电影名称,检查是否重复 bool movie_exists = false; for (const auto& existing_name : names_list) { if (existing_name == name) { movie_exists = true; break; } } if (movie_exists) { cout << "Movie already exists " << endl; } else { auto* new_movie = new Movie{name, watched_times, rating}; included_movies.push_back(new_movie); cout << "Added movie " << name << " Successfully" << endl; names_list.emplace_back(name); } }
额外优化建议
- 优先使用
std::string代替char[]作为函数参数,更安全且符合C++的现代编程风格; - 注意内存泄漏:
included_movies存储的是Movie*指针,在Movies的析构函数中需要遍历容器并delete每个Movie对象; - 遍历容器时尽量使用范围for循环(如上面的代码),避免手动管理计数器带来的越界风险。
内容的提问来源于stack exchange,提问作者KMG
相关产品推荐
相关产品推荐

