【问题标题】:glibc detected - double free or corruption检测到 glibc - 双重释放或损坏
【发布时间】:2012-02-05 21:18:51
【问题描述】:

当我将代码(粘贴在下面)提交到在线 gcc 编译器时,我收到以下错误消息。

* 检测到 glibc /run-1326102706-2046832693/solution: double free or corruption (!prev): 0x091901a8 ** =======

代码如下:

# include <iostream>
# include <string>
# include <list>
# include <cstring>

using namespace std;

int main()
{
    int test_cases, i, score, str_len;
    string str;
    char first_char, current_char;
    list <int> strlist;
    list <int> :: iterator it; 

    cin>>test_cases;

    char *cstr[test_cases]; //Creating an array of cstr pointers (test_cases number of pointers)

    while(test_cases > 0)
    {
        cin>>str;
        first_char = str.at(0);
        str_len = str.length();
        score = str_len;
        strlist.clear();

        cstr[test_cases-1] = new char[str_len];
        strcpy(cstr[test_cases-1],str.c_str()); //copying the input str into cstr. This is done to minimize the complexity of std::string's at function.

        for(i=1;i<str_len; i++)
        {
            current_char = *(cstr[test_cases-1]+i);
            if (current_char == first_char)
            {
                score++; strlist.push_front(1);
                it = strlist.begin();
                if (it != strlist.end())
                    it++;
            }

            while (!strlist.empty() && it != strlist.end())
            {
                if (current_char == *(cstr[test_cases-1] + *(it)))
                {
                    (*it)++;it++;score++;
                }
                else
                    it = strlist.erase(it);
            }
            if (!strlist.empty())
                it = strlist.begin();

        }
        cout<<score<<endl;
        delete(cstr[test_cases-1]);
        test_cases--;

    }

    return 0;
}

正如代码本身所提到的,我最初使用 std::string,但发现 std::string.at 函数非常慢(尤其是因为这个问题的输入字符串非常大)。所以我决定将字符串输入存储在一个字符数组中,这样就可以直接索引到一个特定的位置。

感谢任何帮助。

【问题讨论】:

  • 你试过运行 valgrind 吗?
  • stringc_str 方法可用于从中取出c-style 字符数组。无需为此编写自己的字符串类。
  • 通过什么输入导致崩溃?
  • 因为这是提交给 topcoder 类型的在线编译器 - 我无法控制编译器或输入。不过我可以尝试在本地机器上运行它。

标签: c++ free glibc


【解决方案1】:

我可以看到两个问题:

cstr[test_cases-1] = new char[str_len]; // Not allocating space for terminating NULL.

delete(cstr[test_cases-1]); // Incorrect delete, should be delete[]
                            // As already pointed out by mooware

将这两行改为:

cstr[test_cases-1] = new char[str_len + 1];

delete[] cstr[test_cases-1];

【讨论】:

    【解决方案2】:

    您使用 array-new ("new char[str_len]") 分配字符串,但使用 scalar-delete ("delete(cstr[test_cases-1])") 删除它们。你应该总是匹配 new- 和 delete- 操作符,所以当你使用 array-new 时,也要使用 array-delete ("delete[] cstr[test_cases-1]")。

    【讨论】:

      【解决方案3】:

      你有两个错误。一个在这里:

          cstr[test_cases-1] = new char[str_len];
          strcpy(cstr[test_cases-1],str.c_str());
      

      你分配的一个字节太少了。那应该是new char[str_len+1],因为strcpy 复制了终止符。

      另一个在这里:

          delete(cstr[test_cases-1]);
      

      您不能使用new[] 分配和使用delete 取消分配。如果你用new[]分配,你必须用delete[]去分配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多