【问题标题】:segmentation fault on string assignment字符串分配的分段错误
【发布时间】:2012-05-11 15:32:35
【问题描述】:

我有一个文本文件,其中只包含带有如下消息的行:

你好
你好

现在我得到了这个函数,它读取这些行并返回一个包含它们的数组。

string* printlines(string filename)
{
string line;
int sum = 2;
int i =0;
string *quotes;
ifstream infile(filename.c_str());

quotes= new string[2];

    if (infile.is_open())
    {

      while (infile.good())
      { 
        getline (infile,line);
        quotes[i] = line; // <--- here's the problem
        i++;
       }
    }
infile.close();
return quotes;
}

gdb 报告粗体行有问题,但我没有看到。

【问题讨论】:

  • 很少需要一个函数来返回指向动态创建的字符串对象的指针。只需按值返回字符串。
  • 同样在使用星号作为指针解引用和乘法的语言中,尝试使用星号星号语法加粗一行是不好的。

标签: c++ string segmentation-fault assign


【解决方案1】:

循环结构不正确,将导致超出数组末尾。尽管文件中只有两行,但在getline() 之后不会立即检查以确定是否成功。将读取前两行,但尚未设置 eof,从而导致第三次 getline() 调用,超出数组末尾。

改为:

while (getline(infile, line) && i < 2)
{
    quotes[i] = line;
    i++;
}

话虽如此,考虑使用std::vector&lt;std::string&gt; 代替数组:

std::vector<std::string> quotes;
while (getline(infile, line))
{
    quotes.push_back(line);
}

std::vector 将动态增长以存储所有读取行。无需更改代码即可将新行添加到文本文件中。

【讨论】:

    【解决方案2】:

    如果你读取的行数超过两行,你就会在堆上分配两个字符串,你就有麻烦了。如果你想返回一个动态分配的字符串数组,可以使用std::vector 和类似的东西:

    std::vector<std::string> printlines(const std::string& filename)
    {
        std::vector<std::string> quotes;
        std::ifstream infile(filename.c_str());
    
        if (infile.is_open())
        {
            while (infile.good())
            {
                std::string line;
                std::getline (infile,line);
                quotes.push_back(line);
            }
        }
        infile.close();
    
        return quotes;
    }
    

    这样您就不需要关心读取了多少字符串,它只会不断增长,为所有字符串腾出空间,而且您不必担心内存泄漏,当向量耗尽时,它会删除所有字符串范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多