字符串麻烦

时间:2012-03-01 21:29:39

标签: c++ string ubuntu g++ libstdc++

我正在调试一个相当大的程序。当我来到以下代码行时:

value->binary_string = value_it->binary_string.substr(range->msb->value, range->size);

程序行为不正确。这里的value是一个指向结构的指针,该结构的成员名为binary_string,类型为std :: string。当我在调试时到达此行时,我看到:

value_it->binary_string = "00000000000000000000000000000111"
range->msb->value = 0
range->size = 32

执行此行代码后,value-> binary_string为空!我甚至将线路改为

value->binary_string = value_it->binary_string

它仍然失败!

当我在调试时到达这一行时,我的程序正在使用大约100 Mb的内存,所以我不认为这是一个内存问题(虽然我正在运行Valgrind,因为我们说的是验证这一点)。我使用的是Ubuntu 11.10,g ++ - 4.6和libstdc ++ 6.

以前有没有人遇到这样的事情?我不知道为什么我的琴弦不起作用!

谢谢,

萨姆

EDIT1:

值的类型是NumberInst,定义如下:

typedef std::string String;

struct NumberInst
{
    unsigned size;
    bool signed_;
    String binary_string;
    bool valid;
    unsigned value;

    NumberInst();
};

EDIT2:

看起来我已经缩小了搜索范围。在调试时,我尝试了一些打印命令:

print value_it->binary_string
"00000000000000000000000000000111"
print value_it->binary_string[31]
'1'
print value_it->binary_string.substr(0, String::npos)
""
print value_it->binary_string.substr(0, 1)
""

在这种情况下,似乎substr无法正常工作。但是,当我在我的主函数中测试substr时,似乎工作正常。

2 个答案:

答案 0 :(得分:2)

我发现,当发生类似“奇怪”​​的事情时,通常有两个常见的原因:

  1. 你犯了一个简单的错误,只是忽略它。
  2. 某种内存损坏。
  3. 要检查第一个原因,请仔细阅读有问题的代码,并有意识地决定阅读代码正在做什么,而不是您认为应该做什么。通过假设代码应该执行实际上没有做的事情,很容易忽略明显的错误,特别是在你已经看了一段时间的代码中。例如,几个月前我正在调试一些问题,并且一个变量“神奇地”突然改变它的值。事实证明我只是打印了错误的变量(呃!)如果我一直在阅读代码实际上所说的内容,我会更快地抓住它。

    内存损坏是一个更难找到的野兽,因为它可能发生在问题出现之前的任何时间运行的任何代码中。 Valgrind不保证找到所有形式的腐败,请参阅this question作为示例。在调试模式下运行,设置内存监视点(如果你知道腐败始终发生在哪里)和其他与内存相关的工具可能会有所帮助,因为它会将问题减少到最小的形式...继续消除代码运行一点点,直到腐败不会发生。

答案 1 :(得分:1)

问题是由一个非常微妙的错误引起的。在我的项目的某个地方:

NumberInst* number = new NumberInst;
number->binary_string.reserve(size);
for (unsigned i = 0; i < size; i++)
    number->binary_string[i] = ...;

不会抛出std :: out_of_range异常,因为我假设标准库将数组索引与字符串的容量进行比较(而不是字符串的大小)。在调试器中调用print将成功,因为它可能会遍历缓冲区,直到达到'\ 0'字符。然而

String str = number->binary_string

将失败,因为标准库很可能从[0,size)复制value_it-&gt; binary_string的缓冲区并添加'\ 0'字符。由于value_it-&gt; binary_string的大小为0,因此复制其内容将失败(与substr和依赖于调用字符串大小的其他函数一样)。

换句话说,问题是由调用

引起的
str.reserve(size);

而不是

str.resize(size);

感谢大家的帮助!

萨姆