При запуске приведенного ниже кода я получаю Segmentation fault (core dumped)
.
Мне сказали, что сбои сегментов чаще всего возникают из-за плохих указателей. Я относительно новичок в этом языке, и с учетом сказанного я уверен, что делаю здесь что-то явно не так, но не могу заметить этого из-за моей неопытности и текущего уровня владения языком.
Приведенный ниже код создает vector
из PeekDeque<StringWrap>
объектов в методе main
. Затем он передает указатель на vector
функции testNewWord
. Затем эта функция создает новый объект PeekDeque<StringWrap>
и помещает его в конец vector
. Ну, в любом случае это то, что я пытаюсь сделать!
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
void testNewWord(string word, vector<PeekDeque<StringWrap> >* chains) {
PeekDeque<StringWrap>* newpd = new PeekDeque<StringWrap>(100);
newpd->pushFront(StringWrap(word));
chains->push_back(*newpd);
}
int main(int argc, char* argv[]){
vector<PeekDeque<StringWrap> >* chains = new vector<PeekDeque<StringWrap> >();
string word;
string infileName = argv[1];
ifstream* INFILEp = new ifstream(infileName.c_str(), ios_base::in);
while ((*INFILEp) >> word) {
testNewWord(word, chains);
}
INFILEp->close();
}
Что я здесь делаю не так? Возможно, удаление вызывается для нулевого указателя? Полегче со мной.
3 ответа
Ни одно из мест, где вы используете указатель, на самом деле не должно быть (и не должно быть) указателем. Вместо этого они должны быть обычным объектом, а затем передаваться через ссылки .
Попробуйте заменить:
vector<PeekDeque<StringWrap> >* chains = new vector<PeekDeque<StringWrap> >();
Просто:
vector<PeekDeque<StringWrap> > chains;
А также
void testNewWord(string word, vector<PeekDeque<StringWrap> >* chains) {
PeekDeque<StringWrap>* newpd = new PeekDeque<StringWrap>(100);
С участием:
void testNewWord(const string& word, vector<PeekDeque<StringWrap> >& chains) {
PeekDeque<StringWrap> newpd(100);
Узнайте больше о том, когда следует использовать ссылки вместо указателей. Как правило, в C ++ используйте указатели только в том случае, если вы абсолютно не можете использовать ссылку. Вам также придется изменить все ваши ->
обратно на .
, потому что ссылки действуют так, как будто они являются фактическим объектом, а не указателем на него.
Я не вижу, чтобы вы тестировали свой параметр argc
. Что произойдет, если из командной строки не будет передан параметр?
Кажется, с вашим кодом все в порядке; то, что вы делаете, совершенно законно и правильно. Так что, возможно, что-то еще отсутствует на картинке, например, как вы вызываете свой код
ОДНАКО - у меня есть одно предложение
PeekDeque<StringWrap>* newpd = new PeekDeque<StringWrap>(100);
newpd->pushFront(StringWrap(word));
chains->push_back(*newpd); <----
Для последней строки вызывается конструктор копирования, и вы копируете вновь созданный объект в вектор. Это пустая трата ресурсов. Вы можете заменить vector<PeekDeque<StringWrap> >* chains
на vector<PeekDeque<StringWrap>* >* chains
и удерживать указатели. таким образом вы можете напрямую нажать на указатель и использовать время, потраченное на выделение нового объекта.
PeekDeque<StringWrap>& deque
, заполнив его и вернув void. Затем вы выделили указанный выше массив, поместив пустую двухстороннюю очередь в вектор chains
и передав chains.back()
методу. Если вас беспокоят проблемы с жизненным циклом, а это, как правило, когда вам нужно использовать указатели, вам следует вместо этого попробовать использовать shared_ptr
/smart_ptr
, чтобы выделение памяти выполнялось без необходимости сделать это вручную. Как написано, этот код пропускает память, как решето.
Похожие вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.
gdb my_executable
, а затем набираетеrun
в командной строке. После сбоя введитеbacktrace
, и он сообщит вам точную последовательность шагов, вызвавшую сбой.