Я пишу программу, которая должна анализировать переменную среды PATH по разделителю «:». Кажется, все работает правильно, пока функция chop не попытается вернуть массив. Затем я получаю следующую ошибку: «Обнаружен glibc ./a.out: поврежденный двойной связанный список: 0x08f8f148». Я использую chop, чтобы также проанализировать пользовательский ввод, и он работает правильно. Любая помощь с благодарностью.
//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;
}
Я не знаю, заметили ли вы это или нет, но вы создаете массив указателей на места в пределах std::string
объект x
это имеет локальную область функции. Как только эта функция вернется, эти указатели не гарантированно будут значимыми, потому что x
будет уничтожен
Вы выделяете постоянное хранилище для массива указателей для расколотых слов, но не можете гарантировать, что то, на что они указывают, имеет срок службы, превышающий саму функцию. Если вы ссылаетесь на любой из этих указателей, это будет неопределенное поведение, которое просто может быть причиной вашего повреждения связного списка.
Даже если это не является причиной вашей проблемы, это все равно ошибка, которую необходимо устранить. Похоже, вы адаптировали C-based chop (...)
функция, которая работала на char *
и заменил его std::string
не понимая, что происходит, когда строковый объект выходит из области видимости.
Я столкнулся с этой ошибкой в каком-то коде, где кто-то вызывал exit () в одном потоке примерно в то же время, что и main()
возвращается, вызывая глобальные / статические конструкторы для запуска в обоих потоках.
Эта ошибка также проявляется как double free or corruption
Сегфо / сиг11 внутри exit()
или внутри malloc_consolidate
и, вероятно, другие.
Проблема никогда не обнаруживалась при работе под Valgrind.