Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Укажите на ошибки в упражнении, присвоение с-строкам векторов 
:(
    Опции темы
zim22
Дата 22.1.2009, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Необходимо было выполнить упражение из книги. Я выполнил, но думаю что ошибся в понимании самого упражнения или использованных типов данных.
Укажите, пожалуйста, где я ошибся.

Задание:
1) Напишите программу, читающую строки в вектор. 
2) Скопируйте этот вектор в массив указателей на тип char. 
3) Для каждого элемента вектора создайте новый символьный массив и скопируйте данные из элемента вектора в этот символьный массив. 
4) Затем поместите указатель на символьный массив в массив символьных указателей. 
5) Затем отобразите содержимое вектора и массива. 
6) После отображения не забудьте удалить символьные массивы.

6 пункт не знаю, как сделать... Если удалять их в том блоке, где оператор new использую,  то данные стираются и следовательно отобразить их в пункте 5) я не смогу...
Код

int main()
{
// 1) Напишите программу, читающую строки в вектор. 
    string str;
    vector<string> vs;
    while (cin >> str)
    {
        vs.push_back(str);
    }

//2) Скопируйте этот вектор в массив указателей на тип char. 
// Как динамически создать массив указателей не знаю, поэтому создал на 100 штук явно.
    const size_t max_el = 100;
    const char *acp[max_el];
    
    size_t cnt = 0;
    for (vector<string>::size_type ix = 0; ix != vs.size(); ++ix)
    {
        acp[ix] = vs[ix].c_str();
        ++cnt;
    }

// 3) Для каждого элемента вектора создайте новый символьный массив 
// и скопируйте данные из элемента вектора в этот символьный массив. 
    for (vector<string>::const_iterator ci = vs.begin(); ci != vs.end(); ++ci)
    {        
        char *el = new char[(*ci).size() + 1];
        strcpy(el, (*ci).c_str());

// 4) Затем поместите указатель на символьный массив в массив символьных указателей. 
        acp[cnt++] = el;        
    }

// 5) Затем отобразите содержимое вектора и массива. 
    for (vector<string>::iterator iter = vs.begin(); iter != vs.end(); ++iter)
        cout << *iter << endl;

    for (size_t ix = 0; ix != cnt; ++ix)
    {
        cout << acp[ix] << endl;

// 6) После отображения не забудьте удалить символьные массивы.
// delete [] acp[ix]; не работает, т..к не диманически память выделял. как удалить символьные массивы, созданные ранее?
    }        

    return 0;
}



--------------------
PM MAIL   Вверх
Andrey44
Дата 22.1.2009, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 2
Всего: 26



Цитата(zim22 @  22.1.2009,  12:01 Найти цитируемый пост)
т..к не диманически память выделял

Код

char *el = new char[(*ci).size() + 1];

А это как? Статически?


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
zim22
Дата 22.1.2009, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Andrey44, это динамически smile
Я имел ввиду, что нельзя написать строчку 
Код

delete [] el;

после этой:
Код

 acp[cnt++] = el;  

т.к. данные сотрутся и ниже по коду я не смогу их отобразить оператором cout

пытаюсь символьные массивы удалять  ниже (закомментировал строчку в коде) 
Код

delete [] acp[ix];

код компилируется, но во время выполнения приложение завершается с крит.ошибкой: Debug Assertion Failed! Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)



--------------------
PM MAIL   Вверх
mes
Дата 22.1.2009, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата

// 5) Затем отобразите содержимое вектора и массива. 
    for (vector<string>::iterator iter = vs.begin(); iter != vs.end(); ++iter) 
        cout << *iter << endl; // вывод вектора вижу , а где вывод массива ?

 // а вот тут выведите длину вектора, и длину массива (cnt) -  и будете удивлены smile
 


а виновата строчка 20, к тому же блок 17-21 бессмысленный

Это сообщение отредактировал(а) mes - 22.1.2009, 12:52


--------------------
PM MAIL WWW   Вверх
Andrey44
Дата 22.1.2009, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 2
Всего: 26



zim22, ты смотрел чему равно ix когда ты вызываешь delete [] acp[ix]; ?


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
zim22
Дата 22.1.2009, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Andrey44, смотрел. ix = 0; следовательно в этом участке кода
Код

for (size_t ix = 0; ix != cnt; ++ix)
{
            cout << acp[ix] << endl;        
    delete acp[ix];
}

при первой итерации acp[0] указывает на строку, расположенную по индексу 0.
если например при запуске программы ввести: hello my dear
то 3 строки занесётся в вектор. и acp[0] будет указывать на строку "hello"
так что я до сих пор не понимаю, почему оператор delete не работает

mes, длину вектора и массива вывел. длина массива в 2 раза больше длины вектора. так и должно быть (как я понял) по логике работы программы.
Т.к. после пункта 2 в массиве указателей содержится 3 элемента. А после п.4 ещё 3 элемента, итого 6.

почему код в строках 17-21 бессмысленный?
если конечно вы имеете ввиду этот участок:
Код

for (vector<string>::size_type ix = 0; ix != vs.size(); ++ix)
{
    acp[ix] = vs[ix].c_str();
    ++cnt;
}


Этот код выполняет пункт 2) задания: Скопируйте этот вектор в массив указателей на тип char. 

>// вывод вектора вижу , а где вывод массива ?
вывод массива здесь:
Код

for (size_t ix = 0; ix != cnt; ++ix)
{
    cout << acp[ix] << endl;
}        



--------------------
PM MAIL   Вверх
mes
Дата 22.1.2009, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(zim22 @  22.1.2009,  12:33 Найти цитируемый пост)
mes, длину вектора и массива вывел. длина массива в 2 раза больше длины вектора. так и должно быть (как я понял) по логике работы программы.
Т.к. после пункта 2 в массиве указателей содержится 3 элемента. А после п.4 ещё 3 элемента, итого 6.


Не удивлены ?! то есть Вы в курсе, что создали три элемента, а удаляете шесть ? !!! smile

Цитата(zim22 @  22.1.2009,  12:33 Найти цитируемый пост)
Этот код выполняет пункт 2) задания: Скопируйте этот вектор в массив указателей на тип char. 

а..ну если того требует задание.. просто в контексте кода этот блок не имел смысла...  к тому же он потенциально опасный .. 

Цитата(zim22 @  22.1.2009,  12:33 Найти цитируемый пост)
вывод массива здесь:

сорри, опять моя невнимательность


Это сообщение отредактировал(а) mes - 22.1.2009, 14:40


--------------------
PM MAIL WWW   Вверх
zim22
Дата 22.1.2009, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(mes @  22.1.2009,  14:37 Найти цитируемый пост)
Не удивлены ?! то есть Вы в курсе, что создали три элемента, а удаляете шесть ? !!! 

я создал 6 элементов, а не 3.

здесь "создаётся" (на самом деле Присваивается, правильно?) 3 элемента:
Код

acp[ix] = vs[ix].c_str();


плюс здесь ещё 3:
Код

char *el = new char[(*ci).size() + 1];
strcpy(el, (*ci).c_str());
acp[cnt++] = el;                


итого 6 элементов содержится в переменной acp
*****
добавлено 1 секунду спустя:
гениально! я понял в чём ошибка была!
В самом нижнем цикле нужно поменять
Код

delete acp[ix];

на 
Код

delete acp[ix + 3];


и я буду удалять как раз те 3 строки(последних), которые создавал оператором new.
а первые 3 строки я не мог удалить, т.к. они принадлежали вектору?


--------------------
PM MAIL   Вверх
mes
Дата 22.1.2009, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(zim22 @  22.1.2009,  15:34 Найти цитируемый пост)
и я буду удалять как раз те 3 строки(последних), которые создавал оператором new.
а первые 3 строки я не мог удалить, т.к. они принадлежали вектору? 

вот вот. рад, что Вы сами дошли до понимания smile
только прибавления не достаточно.. надо ограничеть цикл до 3х .


--------------------
PM MAIL WWW   Вверх
zim22
Дата 22.1.2009, 22:28 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



mes, спасибо за напутствующие подсказки.
это прекрасное чувство, когда на тебя "ни-с-того, ни-с-сего" снизоходит озарение и ты понимаешь что в коде было неверно smile


--------------------
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0526 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.