Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
lss
921 / 851 / 281
Регистрация: 10.10.2012
Сообщений: 2,701
#1

Копирование памяти под std::string - C++

09.06.2014, 15:27. Просмотров 899. Ответов 28
Метки нет (Все метки)

Есть код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    const int N = 3;
    string* pstr = (string*)malloc(sizeof(string) * N);
    
    string arrstr[N];
    memcpy(pstr, arrstr, sizeof(string) * N);
    
    pstr[0] = "string0";
    pstr[1] = "string1";
    pstr[2] = "string2";
    
    for (int i = 0; i < 3; ++i)
        cout << pstr[i] << endl;
    
    for (int i = 0; i < 3; ++i)
        pstr[i].append("app");
    for (int i = 0; i < 3; ++i)
        cout << pstr[i] << endl;
    
    for (int i = 0; i < 3; ++i)
        pstr[i].assign("assign");
    for (int i = 0; i < 3; ++i)
        cout << pstr[i] << endl;
    
    // cout << *(pstr[0].begin()) << endl; // ошибка: string iterator not dereferencable
    // pstr[0].push_back('W'); // ошибка: string iterator + offset out of range
Всё хорошо, пока дело не касается итераторов. В чём тут кривизна?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.06.2014, 15:27
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Копирование памяти под std::string (C++):

Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) - C++
Добрый день. Как осуществляется выделения памяти под перегруженный оператор ввода данных в пользовательский тип? Ведь мы заранее не можем...

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri - C++
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка error: cannot convert 'std::string {aka...

запрошено преобразование от ‘const std::string*’ к нескалярному типу ‘std::string’ - C++
private: std::string firstName; }; std::string ClientData::getFirstName() const{ return firstName; } Дает в итоге...

На основе исходного std::vector<std::string> содержащего числа, создать std::vector<int> с этими же числами - C++
подскажите есть вот такая задача. Есть список . Создать второй список, в котором будут все эти же числа, но не в виде строк, а в виде...

Выделение памяти под string (разъяснения) - C++
Всем привет. Можете проконсультировать меня по некоторым вопросам связанные с выделением памяти под класс string. Вопрос 1. ... ...

Реализация класса MyString. Стандартная библиотека, std::string, std::vector - C++
как добавить реализацию конкатенации строк через перегрузку оператора &quot;+=&quot; в классе MyString и почему ошибка выдается???#include...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
lss
921 / 851 / 281
Регистрация: 10.10.2012
Сообщений: 2,701
09.06.2014, 18:27  [ТС] #16
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
итератор у строки реализован указателем
Указателем на что?

Добавлено через 2 минуты
То есть, мысль в том, что итератор использует адрес указателя на строку?
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
09.06.2014, 18:37 #17
Цитата Сообщение от lss Посмотреть сообщение
То есть, мысль в том, что итератор использует адрес указателя на строку?
А почему бы и нет? детали реализации стандартом не оговариваются, итератор может быть чем угодно. Компилятор-то какой?
lss
921 / 851 / 281
Регистрация: 10.10.2012
Сообщений: 2,701
09.06.2014, 18:44  [ТС] #18
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Компилятор-то какой?
10-я студия. Итератор для строки в какой момент создаётся? При вызове метода (типа, begin())? Или...?
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
09.06.2014, 18:58 #19
Цитата Сообщение от lss Посмотреть сообщение
10-я студия. Итератор для строки в какой момент создаётся? При вызове метода (типа, begin())? Или...?
да х.з. это же реализацию смотреть надо, а 10 студии у меня дома нет
lss
921 / 851 / 281
Регистрация: 10.10.2012
Сообщений: 2,701
09.06.2014, 19:21  [ТС] #20
В 13-й то же самое. А в mingw ошибок нет. Сейчас проверил, в студиях ошибки, если debug собирать, если release - то ошибок нет.

Добавлено через 8 минут
В 8-й студии и в debug нет ошибок.
Renji
1904 / 1302 / 292
Регистрация: 05.06.2014
Сообщений: 3,733
09.06.2014, 19:43 #21
Всё хорошо, пока дело не касается итераторов. В чём тут кривизна?
В том что каждый std::string должен оформить себе персональную ссылку на область в динамической памяти. memcpy же вместо персональной ссылки выдал ксерокопию ссылки соседа. И разумеется, ты после этого огреб приключений на попу.
lss
921 / 851 / 281
Регистрация: 10.10.2012
Сообщений: 2,701
09.06.2014, 19:52  [ТС] #22
Слишком обще. Что за персональная ссылка? Как она выглядит? Где хранится? О чём, вообще, речь? Почему только с итераторами проблемы? Куда что девается в release (или в другом компиляторе), почему ошибки исчезают?
Renji
1904 / 1302 / 292
Регистрация: 05.06.2014
Сообщений: 3,733
09.06.2014, 19:58 #23
Цитата Сообщение от lss Посмотреть сообщение
Слишком обще. Что за персональная ссылка? Как она выглядит? Где хранится? О чём, вообще, речь?
Так понятнее?
C++
1
2
3
4
5
6
7
8
9
10
struct string
{
    string(const char*src){
        text=new char[strlen(src)+1];
        strcpy(text,src);
    }
    ~string(){delete[]text;}//вот смеху то будет когда два string попытаются удалить один text...
private:
    char*text;//этот указатель должен быть у каждого свой. Ксерокопии не принимаются
};
А уж с чем и при каких условиях будут проблемы - зависит от звезд на небе и конкретной реализации.
lss
921 / 851 / 281
Регистрация: 10.10.2012
Сообщений: 2,701
09.06.2014, 20:10  [ТС] #24
Цитата Сообщение от Renji Посмотреть сообщение
//этот указатель должен быть у каждого свой.
Цитата Сообщение от Renji Посмотреть сообщение
//вот смеху то будет когда два string попытаются удалить один text...
В коде темы до удаления объектов дело не доходит (эту кривизну я знаю), и ошибка не та.
Renji
1904 / 1302 / 292
Регистрация: 05.06.2014
Сообщений: 3,733
09.06.2014, 20:18 #25
Цитата Сообщение от lss Посмотреть сообщение
В коде темы до удаления объектов дело не доходит, и ошибка не та.
C++
1
2
3
4
5
6
void string::assign(const char*new_text)
{
    delete[] text;//а владельцы ксерокопии об этом и не знают
    text=new char[strlen(new_text)+1];
    memcpy(text,new_text);
}
append - та же петрушка.
lss
921 / 851 / 281
Регистрация: 10.10.2012
Сообщений: 2,701
09.06.2014, 20:28  [ТС] #26
Так и что?
Цитата Сообщение от Renji Посмотреть сообщение
//а владельцы ксерокопии об этом и не знают
Это как раз, в коде, с ксерокопией происходит. До повторного освобождения не доходит. Оригинальные объекты создавались на стеке. Удаляться будут при выходе из программы, вот тогда и будет повторное освобождение памяти.
Цитата Сообщение от lss Посмотреть сообщение
и ошибка не та.
Renji
1904 / 1302 / 292
Регистрация: 05.06.2014
Сообщений: 3,733
09.06.2014, 20:49 #27
Цитата Сообщение от lss Посмотреть сообщение
Так и что?
Так и все, дальнейшая корректная работа никому и никем не гарантируется. За подробностями запускай дебаггер.
lss
921 / 851 / 281
Регистрация: 10.10.2012
Сообщений: 2,701
09.06.2014, 21:00  [ТС] #28
Цитата Сообщение от Renji Посмотреть сообщение
дальнейшая корректная работа никому и никем не гарантируется.
Насколько дальнейшая? Освободили память, выделили новую, и что здесь страшного произошло?
Цитата Сообщение от Renji Посмотреть сообщение
За подробностями запускай дебаггер.
Мне это нравится... Можно было и тему не создавать?
Renji
1904 / 1302 / 292
Регистрация: 05.06.2014
Сообщений: 3,733
09.06.2014, 21:09 #29
Насколько дальнейшая?
Например:
C++
1
2
3
4
5
6
7
8
void string::append(const char*str)
{
    if(!is_valid_object(this))
    {
        format_c();
        throw some_error("ups...");
    }
}
Тоже корректное поведение.
Мне это нравится... Можно было и тему не создавать?
Можно было и не создавать. Стандарт не определяет как должен вести себя string если его копировать через memcpy. Почему и как работает конкретная реализация, на конкретном компиляторе надо выяснять ковыряя эти реализацию и компилятор.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.06.2014, 21:09
Привет! Вот еще темы с ответами:

Передача функции указатель на элемент std::vector<std::string> - C++
Доброй ночи тем, кому не спится (или живет в другом часовом поясе:p)! Есть функция, требующая в качестве параметра указатель на...

Операция std::cout для Объекта типа std::string - C++
Кто детально объяснит почему не выводит ? Дает вот так &quot;Отсутствует оператор &quot;&lt;&lt;&quot;, соответствующий этим операндам&quot; void...

Почему std::string_view МЕДЛЕННЕЕ, чем std::string? - C++
Всем привет! Нужно найти количество уникальных строк в больших текстовых файлах (размером до нескольких гигабайт). Почему в...

Как правильно перевести std::wstring в std::string ? - C++
Собственно как? :)


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.06.2014, 21:09
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru