Динамически размещаемый массив строк C - PullRequest
2 голосов
/ 07 августа 2011

Мне непонятно, почему это должно потерпеть неудачу, и почему это терпит неудачу, где это происходит:

std::string* s;
s = (std::string*)malloc(sizeof(std::string) * 10);
s[0] = "string0";
s[1] = "string1";
s[2] = "string2"; //Segmentation fault

Неважно, каков размер строк, назначенных s [0] - s [2], или сколько места занято malloc'ом. То же самое происходит с QStrings. Я предполагаю, что проблема возникает из-за того, что std :: string содержит внутренний указатель, поэтому sizeof () просто возвращает размер указателя, но, учитывая, что std :: strings ведут себя как значения в противном случае (=, == и т. Д. ) Я не понимаю, почему это влечет за собой неудачу здесь.

Кроме того, для совместимости с другим кодом мне нужно использовать здесь массивы C, а не, например. станд :: вектор. И я ищу общее решение (которое будет работать с QString, QDateTime и т. Д.), Если оно есть. Но я был бы рад узнать, что происходит.

Редактировать: Пониженное голосование ... Что не так с этим вопросом? Сначала я какое-то время оглядывался по сторонам (включая SO), но не нашел этого адреса.

Ответы [ 6 ]

10 голосов
/ 07 августа 2011

Вы не можете malloc массив объектов класса, потому что эта функция не вызывает никаких конструкторов.Вы просто наполняете память мусором, который затем пытаетесь интерпретировать как массив объектов класса.

Массивы объектов C ++ выделяются с new[].

Что касается совместимости с другим кодомвы, вероятно, можете использовать std::vector, потому что &vec[0] дает вам указатель на первый элемент в непрерывном массиве.


Если вы настаиваете на использовании malloc и free, то выВам нужно будет вручную вызывать конструктор для каждого элемента массива с новым размещением и вручную вызывать каждый деструктор перед освобождением.

5 голосов
/ 07 августа 2011

Проблема в том, что std :: string имеет конструктор, который должен быть вызван.

Не то, чтобы иметь массив строк - это хорошая идея, но если вам необходимо:

string* s = new string[10];
3 голосов
/ 07 августа 2011

Проблема возникает из-за того, что вы не должны использовать malloc для выделения пространства для классов с конструкторами (например, std :: string), если вы действительно не знаете, что делаете. Сделай это простым способом и используй новый

std::string* s;
s = new std::string[10];
s[0] = "string0";
s[1] = "string1";
s[2] = "string2";

Техническая причина того, что ваш код не работает, состоит в том, что вы не сконструировали ни одну из своих строк, потому что вы не вызвали их конструкторы, все, что у вас есть, - это блок неинициализированной памяти. С другой стороны, new вызывает конструктор std :: string в памяти, которую он выделяет.

1 голос
/ 07 августа 2011

Как уже упоминалось:

You can not malloc an array of class objects, because this

функция не вызывает никаких конструкторов.Вы просто заполняете память мусором, который затем пытаетесь интерпретировать как массив объектов класса.

Если вы хотите [в качестве обходного пути], сделайте следующее:

char * s [10];

для (int i = 0; i <10; i ++) s [i] = новый символ [10]; </p>

strcpy (s [0],"string0");

strcpy (s [1], "string1");

strcpy (s [2], "string2");

1 голос
/ 07 августа 2011

с malloc, конструктор std :: string не вызывается. Это может быть причиной. Кстати, зачем использовать malloc для выделения памяти, когда вы используете std :: string? Что мешает вам использовать новый?

0 голосов
/ 07 августа 2011

То, что вы, вероятно, хотите, это вектор строк:

std::vector<std::string> s(3);
s[0] = "string0";
s[1] = "string1";
s[2] = "string2";

Кроме того, для совместимости с другим кодом мне нужно использовать здесь массивы C, а не, например. станд :: вектор

Вы можете получить необработанный указатель на первый элемент для взаимодействия с устаревшим кодом:

string* p = &s[0];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...