LittleFatNinja
@LittleFatNinja
горе девелопер, любитель лютой садомии

C++ teplate class. Пoмогите! Почему вылетает segfault при попытке запихнуть std::string?

помогитее!!! уже не знаю что делать
пишу типа std::vector-а
допустим выделяю 100 байт, если создать список с int-ами, то все ок, если же со std::string то получаю segmentation fault при добавлении. вроде все правильно делаю, память выделяется, перепробовал все что знал и гуглил
ArrayList<int> *list = new ArrayList<int>();
list->push_back(5);  // ok

ArrayList<string> *list = new ArrayList<string>();
list->push_back("hello");  // segfault


template <class Type> 
class ArrayList {

private:
	Type *array;

public:
	ArrayList() : {
		array = (Type*) malloc(100);
	}
	~ArrayList() {
		free(array);
	}

	void push_back(Type elem) {
		array[0] = elem;
	}

const Type& operator[](size_t index) const {
	    return array[index];
	}
};
  • Вопрос задан
  • 775 просмотров
Решения вопроса 2
@xibir
array[0] = elem;
это означает вызов
array[0].operator=(elem);
в функции "string::operator=()" и падает, т. к. в array[0] находится мусор, потому что для него (для array[0]) конструктор не вызывался

Вместо
array = (Type*) malloc(100);
возможно имелось ввиду
array = new Type[100];
а место free, тогда delete[]array
Ответ написан
@MarkusD Куратор тега C++
все время мелю чепуху :)
Штука первая, делать надо не так:
array = (Type*) malloc(100);
а так:
array = new Type[ 100 ];
или, лучше, вот так:
array = static_cast<Type*>( new uint8_t[ 100 * sizeof( Type ) ] );


Штука вторая. У тебя в выделенном блоке памяти мусор лежит. Надо сперва память подготовить. Делаем вот так:
memset( array, 0, 100 * sizeof( Type ) );
Это приведет к очистке памяти. Но и после этого память все еще нельзя использовать.

Следом надо переделать вот так:
void push_back(Type elem) {
    new( array ) Type();
    array[0] = elem;
  }

или так:
void push_back(Type elem) {
    new( array ) Type( elem );
  }
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Vinatorul
@Vinatorul
Developer
Ну начнём с того, что string в с++ это объект std::string.
Type *array получается указатель на объект типа string.
Вы выделяете 100 байт памяти и указатель на эту память преобразуете в указатель на объект типа std::string.
А потом в эти 100 байт пытаетесь записать объект, который, очевидно, имеет размер больше 100 байт.

UPD
Попробуйте добавить больше 25 элементов типа int или более 12 элементов типа double - получите тот же segfault

UPD2
Вообще обычно такие вещи делают связным списком

UPD3
Нашел несложную реализацию двусвязного списка на хабре.
Ответ написан
@dmtrrr
Backend developer
1) string это объект, он занимает в памяти больше, чем вы предполагаете
2) прочитайте про временные объекты
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы