Я получаю segfault на MacOSX («Ошибка сегментации: 11», в gdb «Сигнал программы SIGSEGV, ошибка сегментации»), появляющийся в деструкторе в котором контейнер зацикливается с итератором и память удалена. Я пробовал с clang ++, g ++ (обе части LLVM) и homebrew g ++. Выдаёт ошибку сегментации появляется, когда итератор увеличивается в первый раз, с сообщением GDB (будучи скомпилирован с лязгом ++)C++ segfault на одной платформе (MacOSX), но не другой (linux)
"0x000000010001196d in std::__1::__tree_node_base<void*>* std::__1::__tree_next<std::__1::__tree_node_base<void*>*>(std::__1::__tree_node_base<void*>*)()"
При запуске программы в GDB я также получить предупреждение о том, «предупреждение: не удалось открыть OSO архивный файл ».
На кластерном узле linux, с gcc 4.8.1, я не получаю segfault. Любые идеи, что может быть неправильным, и как я могу избежать segfault на моем mac (желательно с clang)? Я действительно мало знаю о компиляторах и тому подобных.
EDIT:
Я думаю, что я нашел эту проблему, однако я хотел бы понять, почему это до сих пор работает на одной платформе, но не другой. Вот минимальный пример:
класс Слово:
#ifndef WORD_H
#define WORD_H
#include <string>
#include <map>
class Word {
public:
/*** Constructor ***/
Word(std::string w) : m_word(w) {
// Add word to index map, if it's not already in there
std::map<std::string, Word*>::iterator it = index.find(w);
if (it == index.end()) {
index[w] = this;
}
}
~Word() { index.erase(m_word); } // Remove from index
static void DeleteAll() { // Clear index, delete all allocated memory
for (std::map<std::string, Word*>::const_iterator it = index.begin();
it != index.end();
++it)
{ delete it->second; }
}
private:
std::string m_word;
static std::map<std::string, Word*> index; // Index holding all words initialized
};
#endif
WordHandler класс:
#ifndef _WORDHANDLER_H_
#define _WORDHANDLER_H_
#include <string>
#include "Word.h"
class WordHandler {
WordHandler() {}
~WordHandler() { Word::DeleteAll(); } // clear memory
void WordHandler::NewWord(const std::string word) {
Word* w = new Word(word);
}
};
#endif
Основная программа:
#include <iostream>
#include "WordHandler.h"
int main() {
std::cout << "Welcome to the WordHandler. " << std::endl;
WordHandler wh;
wh.NewWord("hallon");
wh.NewWord("karl");
std::cout << "About to exit WordHandler after having added two new words " << std::endl;
return 0;
}
Так выдаёт ошибку сегментации происходит при выходе из программы, когда вызывается деструктор ~ WordHandler. Причина, по которой я нашел, - это деструктор Word: объект Word стирается с карты, что делает функцию DeleteAll() странной, потому что карта изменяется во время ее повторения (что-то вроде двойного удаления, я полагаю). Segfault исчезает либо путем полного удаления DeleteAll, либо удаления деструктора Word.
Так что мне все еще интересно, почему segfault не появляется на linux с g ++ из gcc 4.8.1. (Кроме того, я предполагаю, что не по теме, я задаюсь вопросом о самом программировании - то, что было бы правильным способом лечения удаление индекса стирания/памяти в этом коде?)
EDIT 2:
Я не думаю, что это дубликат Vector.erase(Iterator) causes bad memory access, потому что мой первоначальный вопрос был связан с тем, почему я получаю segfault на одной платформе, а не в другой. Возможно, другой вопрос объясняет segfault как таковой (не знаю, как обойти эту проблему ... возможно, удалить деструктор Word и удалить удаление из DeleteAll(), а не «удалить»? Но этот деструктор имеет смысл для меня, хотя .. .), но если это действительно ошибка в коде, почему GSC g ++ не подхвачен?
Возможно, у вас [* неопределенное поведение *] (https://en.wikipedia.org/wiki/Undefined_behavior), но, не имея возможности увидеть соответствующий код, трудно сказать что-то более конкретное. Создайте [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve) и покажите нам. –
Вы удаляете объект, на который указывает итератор, а затем пытаетесь его увеличить? – Buddy
Возможный дубликат [Vector.erase (Iterator) вызывает плохой доступ к памяти] (http://stackoverflow.com/questions/2943912/vector-eraseiterator-causes-bad-memory-access) –