C++: glibc обнаружил поврежденный двусвязный список: 0x08f8f148

Я пишу программу, которая должна анализировать переменную окружения PATH в разделителе ":". Кажется, все работает правильно, пока функция Chop не попытается вернуть массив. Затем я получаю следующую ошибку: «Обнаружен glibc ./a.out: поврежденный двухсвязный список: 0x08f8f148». Я использую отбивную также для анализа пользовательского ввода, и он работает правильно. Любая помощь приветствуется.

//Parse environment variable
    char const* pPath = getenv("PATH");
    if (pPath == NULL){;}
    else{
        string ePath(pPath);
        envp = chop(ePath,':');
    }

char **chop(string s, char c){
    int i, j, k, len, words = 0;
    len = s.length();
    //determine # of words
    for(i=0;i<len+1;i++){
        if(s[i] == c || s[i] == '\0'){words++;}
    }
    char **array;
    string x;
    //allocate memory for char pointers
    if((array=(char**)malloc((words+1)*sizeof(char*))) == NULL){return NULL;}
    array[0] = &x[0];
    i = 0; k = 0;
    //split string on char c
    for(j = 1; j < (words+1); j++,k++,i++){
        //read in characters until delimiter
        while (s[k] != c && s[k] != '\0'){

            x[i] = s[k];
            i++; k++;
        }
        x[i] = '\0';
        array[j] = &x[i+1];
    }
    array[j] = 0;
    return array;   
}

person user2829557    schedule 30.09.2013    source источник
comment
Ошибка не в коде, который вы показали. Скорее всего вы что-то дважды удаляете.   -  person David Hammen    schedule 30.09.2013


Ответы (2)


Я не знаю, заметили вы это или нет, но вы создаете массив указателей на местоположения внутри std::string объекта x, который имеет локальную область действия. Как только эта функция вернется, эти указатели не обязательно будут осмысленными, потому что x будет уничтожен.

Вы выделяете постоянное хранилище для массива указателей для нарезанных слов, но не можете гарантировать, что то, на что они указывают, имеет срок жизни больше, чем сама функция. Если вы сошлетесь на любой из этих указателей, это будет неопределенное поведение, которое просто может быть причиной повреждения вашего связанного списка.

Даже если это не является причиной вашей проблемы, это все равно ошибка, которую необходимо устранить. Похоже, вы адаптировали основанную на C функцию chop (...), которая работала с char *, и заменили ее на std::string, не понимая, что происходит, когда строковый объект выходит за пределы области видимости.

person Andon M. Coleman    schedule 30.09.2013

Я столкнулся с этой ошибкой в ​​каком-то коде, где кто-то вызывал exit() в одном потоке примерно в то же время, когда возвращался main(), в результате чего глобальные/статические конструкторы запускались в обоих потоках.

Эта ошибка также проявляется как double free or corruption, segfault/sig11 внутри exit() или внутри malloc_consolidate и, вероятно, другие.

Проблема никогда не проявлялась при работе под valgrind.

person Brian Vandenberg    schedule 12.02.2015