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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Heap corruption detected 
V
    Опции темы
Pitlord
Дата 3.11.2009, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: нет
Всего: 7



Код

#include <iostream>

using namespace std;

int main()
{
    char *s;

    s = new char[2];
    cin >> s;
    delete s;
}

Если ввести более 1-ого символа, то на строчке с delete появляется ошибка: "HEAP CORRUPTION DETECTED after normal block ... CRT detected that the application wrote to memory after end of heap buffer".

Как я могу вообще контролировать то, что пользователь ввёл больше положенного количества символов? Посимвольно записывать строку?
По-моему, на C с malloc() такой ошибки не было (я так понимаю, что это было небезопасно).
PM MAIL   Вверх
jonie
Дата 3.11.2009, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



Pitlord, ошибки может и не быть (даже для new), но это вас не спесат от более жестких проблем в будущем ))
используйте cin.getline например для работы...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Pitlord
Дата 3.11.2009, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: нет
Всего: 7



Спасибо
PM MAIL   Вверх
Pitlord
Дата 3.11.2009, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: нет
Всего: 7



Код

#include <iostream>

using namespace std;

int main()
{
    char *s;

    cout << "1" << endl << "> ";
    s = new char[10];
    cin.getline(s, 10);
    cout << s << endl;
    delete s;

    cout << "2" << endl << "> ";
    s = new char[10];
    cin.getline(s, 10);
    cout << s << endl;
    delete s;

    system("PAUSE");
}

Если ввести больше 9-ти символов, то во второй случай вообще проскакивается. Я так понимаю, что после введённой пользователем строки будет '\n', а после (не уверен) — 0x00. Как освободить буфер ввода, чтобы со вторым вызовом не было проблем?

Это сообщение отредактировал(а) Pitlord - 3.11.2009, 23:07
PM MAIL   Вверх
bsa
Дата 3.11.2009, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



почитай про istream::ignore();

Вообще-то, я бы рекомендовал пользоваться std::string и std::getline - это гораздо проще и безопасней.
PM   Вверх
Pitlord
Дата 3.11.2009, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: нет
Всего: 7



А длину string'а вообще можно как-то ограничить?
PM MAIL   Вверх
bsa
Дата 4.11.2009, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



а смысл? getline тебе прочтет всю строку, затем, если очень нужно, можешь использовать std::string::resize(), чтобы уменьшить размер до необходимого.
PM   Вверх
Pitlord
Дата 4.11.2009, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: нет
Всего: 7



Ну фактически можно таким образом забить всю оперативную память на какой-то момент. Ну, в принципе, сейчас подойдёт, спасибо.
PM MAIL   Вверх
bsa
Дата 4.11.2009, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



ну если у тебя задача критичная и ей могут такие данные передать, то используй std::istream::getline()...
PM   Вверх
just_geek
Дата 4.11.2009, 05:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 1
Всего: 10



А почему никто не поправил про delete? надо же delete[] s; в данном случае...
PM MAIL   Вверх
Pitlord
Дата 4.11.2009, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: нет
Всего: 7



just_geek, да, верно, спасибо
PM MAIL   Вверх
Pitlord
Дата 4.11.2009, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: нет
Всего: 7



А где-нибудь есть исходники класса string? Интересует тот момент, как там постепенно выделяется память под данные.
PM MAIL   Вверх
Alca
Дата 4.11.2009, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Код

delete [] s;



--------------------
PM WWW ICQ Skype Jabber   Вверх
Pitlord
Дата 4.11.2009, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: нет
Всего: 7



Alca, это уже комментировали
PM MAIL   Вверх
bsa
Дата 5.11.2009, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(Pitlord @ 4.11.2009,  22:05)
А где-нибудь есть исходники класса string? Интересует тот момент, как там постепенно выделяется память под данные.

класс std::string - это 
Код
namespace std {
typedef basic_string<char> string;
}
Таким образом, раз basic_string является шаблоном, то его определение должно быть в хидере. Для получения доступа к std::string ты подключаешь <string>. Вот открой этот хидер и смотри, что подключает он. У GCC, например, выделяется ровно столько, сколько необходимо.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

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

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

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

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


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

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


 




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


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

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