「C++ Primer」3.22 迭代器未定义操作导致段错误问题

在调试C++程序时,遇到输入多行空字符串时出现段错误的问题。问题源于当getline读取仅含换行符的字符串时,vector对象实际为空。while循环中,尾后迭代器被非法解引用,导致段错误。解决方案是正确处理边界条件,避免对无效迭代器的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Title:
/* Revise the loop that printed the first paragraph in text
* to instead change the elements in text that correspond
* to the first paragraph to all uppercase.
*由于目前进度,没有直接从text文本中获取输入,基本实现即使从CLI获取字符串输入(text),然后将第一段非空的字符串大写输出
*/

1)问题描述:


调试过程中发现,当输入多行字符串都为空值时最后在输出时候会出现“段错误”。



修改后源代码如下:

 #include <iostream>
#include <string>
#include <vector>
using std::cout;
using std::cin;
using std::endl;
using std::vector;
using std::string;
int main()
{
    vector<string> text;
    for (string line; getline(cin, line);) text.push_back(line);
    auto temp=text.begin();
    if((*temp).empty())
    {
        // while((*temp).empty()&&temp!=text.end()):判断text.end()的条件在后面的话,可能会产生段错误!!!
        while(temp!=text.end() && (*temp).empty())
        temp++;
    }

    if(temp==text.end())
    {
        std::cerr<<"No data in the text?? boni!!"<<endl;
        return -1;
    }
    else
    {
    for(auto &charater:*temp)
        {
            charater=toupper(charater);
        }
        cout<<"Print out the text which you type:"<<endl;
        for(auto tmp=text.begin();tmp!=text.end();tmp++)
        cout<<*tmp<<endl;
    }
        return 0;
}  


2)处理过程

从上面代码中可以看出,在被注释掉的那行就是引起段错误的根因。

        // while((*temp).empty()&&temp!=text.end()):判断text.end()的条件在后面的话,可能会产生段错误!!!

主要原因是:

1.当键入的字符串只有换行符("\n")没有其他内容时,getline的处理方式是“从给定的输入流中读入内容,直到遇到换行符为止(注意换行符也被读进来了),然后把所读的内容存入到那个string对象中去(注意不存换行符)”,意思就是说,在这种场景下,实际上vector对象text实际上是空文本;

2.当while 循环处理到temp=text.end()时,实际上此时的temp是一个尾后迭代器,这个迭代器没什么实际含义,仅是一个标识,同时不能对该迭代器执行解引用,因为是未被定义的行为;


while((*temp).empty()&&temp!=text.end()):

在这种输入场景下,当“(*temp).empty()”的位置在“temp!=text.end()”前面时,while()语句先执行前者,然后在尝试执行后者进行与判断,但是此时temp刚好等于“text.end()",所以这个行为是非法的。

从而在执行的时候产生段错误。


3)小结

附图红色框出部分为调试前后的对比,最后定位为由于对迭代器非法解引用导致“段错误”:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值