Ошибка сегментации в конструкторе

Это происходит с КАЖДЫМ классом, который я пытаюсь создать на C ++. При переходе с java проблемы возникают в основном при создании классов. Я запускаю valgrind и, похоже, он в конструкторе.

==30214== Memcheck, a memory error detector
==30214== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==30214== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==30214== Command: ./CoC
==30214== 
==30214== 
==30214== Process terminating with default action of signal 11 (SIGSEGV)
==30214==  Bad permissions for mapped region at address 0x404B4F
==30214==    at 0x4C2B9EC: strcat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30214==    by 0x404220: Model::Model(std::string) (in /home/kronus/Apollo/CoC)
==30214==    by 0x402617: main (in /home/kronus/Apollo/CoC)

Как видите, я пытаюсь вызвать конструктор этого класса модели в основной метод. Вот код конструктора

Model::Model(std::string filename)
{
m_TotalFaces = 0;
m_model = lib3ds_file_load(filename.c_str());
    // If loading the model failed, we throw an exception
    if(!m_model)
    {
           throw strcat("Unable to load ", filename.c_str());
    }
}

Когда он вызывается, он закрывается с ошибкой сегментации. Важно: я объявил класс внутри файла заголовка. Это когда я получаю ошибку. Я помещаю класс в исходный файл, и он работает нормально. Что я делаю неправильно?


person Larry Hart    schedule 24.03.2013    source источник
comment
подход C ++ - манипуляции со строкой C без необходимости использовать для выброса будет throw std :: runtime_error (Невозможно загрузить + имя файла)   -  person sylvain.joyeux    schedule 24.03.2013


Ответы (2)


strcat пытается записать строку, на которую указывает второй аргумент, в конец строки, на которую указывает первый аргумент. Поскольку первый аргумент является строковым литералом (который следует рассматривать только для чтения), вы получаете неприятный segfault.

Я предлагаю изучать C ++ так, как будто это совершенно другой язык по сравнению с Java, потому что в противном случае вы можете подумать, что похожие функции работают одинаково. Это опасно. Обезьяна может выучить Java, размять мордочку по клавиатуре. C ++ имеет неопределенное поведение, которое может работать правильно на вашем компьютере, но запускать ядерные ракеты на другом.

person autistic    schedule 24.03.2013
comment
почти третий ответ у вас, и вы очень красиво объясните. - person Grijesh Chauhan; 24.03.2013
comment
Ты потрясающий, ха-ха. Благодаря тонну. Постараюсь не засыпать этот сайт своими глупыми вопросами, но я узнал кое-что новое! Ха-ха. Думаю, вы можете сказать мне, почему он работает, когда он вызывается из источника? Как это было вызвано из заголовочного файла. Потому что это продолжает происходить со мной ... - person Larry Hart; 24.03.2013
comment
Неопределенное поведение ... Иногда неопределенное поведение кажется работающим, иногда - нет. Отчасти поэтому это так опасно. Какую книгу ты читаешь? - person autistic; 24.03.2013
comment
Вот этот. bookholder.com/images/books/super/0135289106.jpg Это просто .. каждый раз, когда я пытаюсь создать класс, он делает это. Теперь это похоже на любой класс, у которого изменена какая-то память. Значит, я не могу сделать это с классом на C ++? - person Larry Hart; 24.03.2013
comment
Вы не можете и не должны, по крайней мере, в C ++. strcat будет приемлемым в коде C, но в коде C ++ есть разные способы делать что-то (см., например, комментарий sylvian.joyeux к вашему вопросу). При попытке получить URL-адрес возникла следующая ошибка: bookholder.com /images/books/super/0135289106.jpg .... Скажите, пожалуйста, название книги и авторов, которые ее написали. - person autistic; 24.03.2013
comment
C ++ Как программировать, Х. М. Дитель / П. Дж. Дитель. Итак, с этим классом. Я хочу, чтобы это было в отдельном отдельном источнике. Как я могу это сделать? - person Larry Hart; 24.03.2013
comment
Итак, поместите его в отдельный отдельный исходный файл. Что с этим не так? Вам нужно знать, где находится руководство для вашего компилятора? Какой компилятор вы используете? - person autistic; 24.03.2013
comment
Я делаю это, но когда я добавляю к нему файл заголовка, чтобы я мог использовать его как «объект» (если бы я его так назвал ...), я получаю эту ошибку. - person Larry Hart; 24.03.2013
comment
Получаете ли вы какие-либо предупреждения при компиляции кода? Пожалуйста, ответьте на мои вопросы ... все из них. - person autistic; 24.03.2013
comment
Мне очень жаль, ха-ха, я использую GCC, и никаких предупреждений. - person Larry Hart; 24.03.2013

Вы добавляете неправильную постоянную строку:

strcat("Unable to load ", filename.c_str());
         ^ you can't append to constant

Прочтите это: исключение c ++: выброс std :: string
Возможно, вы захотите избежать использования строк в качестве классов исключений, потому что они сами могут вызывать исключение во время использования.

второй: Какой тип я должен поймать если я выброшу строковый литерал?

person Grijesh Chauhan    schedule 24.03.2013
comment
В идеале бросить настоящий std::exception или одно из его производных. - person WhozCraig; 24.03.2013