在Cygwin但不是VS的Segfault,有什么想法吗?

时间:2011-06-16 06:53:36

标签: c++

它适用于Visual Studio,但在Cygwin中是段错误,这很奇怪,因为我正在编译相同的源,并且都生成Windows可执行文件。由于某些原因,GDB在Cygwin中对我不起作用,并且VS中没有出现错误,所以我无法在那里进行调试。

有什么想法吗?

int main(void)
{
    Pair ***occurences = new Pair**[20];

    int i, j, k;
    for (i = 0; i < 20; i++)
    {
        occurences[i] = new Pair*[i+1];

        for (j = 0; j < i+1; j++)
        {
            occurences[i][j] = new Pair[26];

            for (k = 0; k < 26; k++)
            {
                Pair pair;
                pair.c = k + 'a';
                pair.occurs = 0;
                occurences[i][j][k] = pair;
            }
        }
    }

    std::fstream sin;
    sin.open("dictionary.txt");
    std::string word;

    while (std::getline(sin, word))
    {
        if (word.size() < 21)
        {
            for (i = 0; i < word.size(); i++)
            {
                // SEGFAULTING HERE
                occurences[word.size()-1][i][word[i] - 'a'].occurences++;
            }
        }
    }

    for (i = 0; i < 20; i++)
    {
        for (j = 0; j < i+1; j++)
        {
            delete [] occurences[i][j];
        }
        delete [] occurences[i];
    }
    delete [] occurences;

    return 0;
}

2 个答案:

答案 0 :(得分:3)

您将此行标记为关键点:

occurences[word.size()-1][i][word[i] - 97].occurs++;

这里所有三个数组访问都可能出错,您必须全部检查:

似乎数组的第一个维度的长度为20,因此索引的有效值为[0..19]。如果单词的大小本身为零,则word.size()-1将小于0;如果单词的大小为21或更大,则{{1}}将大于19。

您确定单词的长度始终在[1..20]范围内吗?

第二个维度具有可变长度,具体取决于第一个维度的索引。你确定这永远不会超出界限吗?

第三个方面让我感到最明显。从字符代码中减去97,并将结果作为索引用于包含26个条目的数组。这假设所有字符都在[97..122]范围内,意思是['a'..'z']。你确定输入中永远不会有其他字符吗?例如,如果有任何大写字符,则结果索引将为负数。

答案 1 :(得分:1)

重新评价我的评论作为答案:

occurences[word.size()-1][i][word[i] - 'a'].occurs++;

如果word.size()为100(例如),这将会崩溃(对于i == 0),因为occurences只有20个元素。