gcc, c ++: переменная статического строкового члена вызывает повреждение / сегментацию кучи - PullRequest
0 голосов
/ 19 августа 2010

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

utilities.c        - compiled with -fPIC and used ar and ranlib to create utilities.a.
dynamicallyloaded.c- compiled with -fPIC and -shared and linked with utlities.a to generate dynamicallyloaded.so 
main.c             - compiled with -fPIC and linked with utilities.a to create main. main dynamically loads and uses dynamicallyloaded.so .
utilities.h        - delclared a class IfTrackerFile with AubFileName as a static string member like   static string          AubFileName;

utilities.cpp      - defines the static variable: string IfTrackerFile::AubFileName;

valgrind out говорит, что в строке неверно free / delete / delete: строка IfTrackerFile :: AubFileName;

Понятия не имею, что происходит. искренне признателен за любую помощь / направление в этом отношении.

Ответы [ 2 ]

1 голос
/ 19 августа 2010

Я предполагаю, что вы получили две разные копии IfTrackerFile::AubFileName. Один, вытягивая его прямо в вашей программе из utilities.a, а другой, когда вы динамически загружаете dynamicallyloaded.so. Я предполагаю, что это сбило с толку систему для уничтожения всех статических и глобальных объектов при завершении работы программы, и в итоге вы дважды вызвали деструктор.

Не думаю, что вы должны смешивать файлы .a и .so таким образом. Как правило, хорошее правило - никогда не связывать файл .so с .a, даже если вы добавили код -fPIC в .a.

0 голосов
/ 19 августа 2010

Это выстрел в темноте, но проблема может быть в глобальных объектах. Создание класса как глобальной переменной означает, что переменная создается перед вызовом main (). Это означает, что конструктор вызывается до запуска main (), а деструктор вызывается после завершения main. Порядок вызова конструктора и деструктора также не определен.

Мой совет - превратить все глобальные объекты (глобальные переменные, которые не являются простыми старыми данными - POD-типы) в указатель, который создается в начале main и уничтожается в конце main.

...