2013-10-13 5 views
2

Ниже фрагмент кода запускается в linux, и он сообщает о сбое сегментации (Core Dump). Я обнаружил, что ошибка возникает при вызове деструктора, но не может понять, почему. Может кто-нибудь помочь объяснить это?Почему этот код дает ошибку сегментации

class TStringPair{ 
    public: 
     TStringPair(){ 
      memset(this, 0, sizeof(TStringPair)); 
     } 


     string a; 
     string b; 
    }; 

    int main (int argc, char* argv[]) 
    { 
     TStringPair test; 
     return 0; 
    } 
+2

C++ == не использовать memset – aaronman

+0

По умолчанию класс инициализируется значениями по умолчанию, равными 0 в большинстве случаев. Использование memset уничтожает любые значения, отличные от 0, которые должны были быть там. –

ответ

4

Это memset руины ваш класс вполне буквально. Память std::string (как и многие другие классы C++) не должна заполняться нулями, но вы заполняете оба.

Чтобы проиллюстрировать, почему это плохая идея, рассмотрите std::string с указателем на фактические символы. К сожалению, вместо указания на нулевую строку он теперь указывает на 0. Есть и другие причины, по которым обнуление объекта, отличного от C, является плохим, но они не совсем уместны для этого примера.

Я представляю себе удаление memset и ничего не помещая на его месте, даст точный результат, который вы собирались сделать.

+0

Ударьте меня буквально на 7 секунд. –

+0

@ColeJohnson, Ну, я понял во время моего второго расширения свой комментарий, что, вероятно, это было лучше, как ответ: p – chris

+0

Конечно, на большинстве платформ указатель NULL состоит из нулевых байтов ... так что, вероятно, это не так. Ваша точка стоит; memset() - память объекта, отличного от POD C++, является no-no. –

2

Перед тем как тело вашего конструктора TStringPair запускается, конструктор по умолчанию std :: string вызывает по умолчанию (автоматически) для каждого из ваших двух элементов-членов-членов.

Конструктор std :: string по умолчанию задает содержимое этих двух объектов в правильное состояние. Что это за правильное состояние? Мы не знаем (не смотря на исходный код STL, так или иначе), но это нормально, потому что нам не нужно знать - мы можем полагаться на реализаторов класса std :: string, чтобы делать правильные вещи.

Однако после запуска этих конструкторов ваш memset проходит и перезаписывает (независимо от того, что они написали) с нулевым байтом ... теперь эти строковые объекты находятся в поврежденном состоянии, поэтому неудивительно, что вы получаете сбой, когда их деструктор бежит и сталкивается с этой коррупцией.

Смежные вопросы