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

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

Войти
Регистрация
Восстановить пароль
 
VV_RIP
9 / 8 / 1
Регистрация: 05.02.2012
Сообщений: 105
#1

EAccessViolation, если длина строки больше 14 - C++

21.02.2013, 20:30. Просмотров 320. Ответов 4
Метки нет (Все метки)

Здравствуйте! Сперва простой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void cyr_print(const char* text)
{
    const int n = strlen(text);
    char *buf = new char[n];
    CharToOem(text, buf);
    cout<<buf<<endl;
    delete buf;
}
//---------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
    char *arr1 = new char[0];
    char *arr2 = new char[0];
    cyr_print("Введите первую строку: ");
    cin>> arr1;
    cyr_print("Введите вторую строку: ");
    cin>> arr2;
    delete arr1;
    delete arr2;
 
    system("pause");
    return 0;
}
Если вводить в консоли до 15 символов в каждый массив, то все работает, если 15 и больше, то ошибка.
Мне интересно, почему именно 15? при этом мы можем на самом деле ввести хоть 30, и все будет норм, программа вылетит только после строчки

C++
1
return 0;
Как так?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.02.2013, 20:30     EAccessViolation, если длина строки больше 14
Посмотрите здесь:

Программа должна определить длину введенной строки L и, если длина L >15, то удаляются все a..z. C++
C++ Ввести строку символов, если ее длина нечетная, удалить символ, стоящий посередине строки.
C++ Найти количество последовательностей положительных чисел, длина которых больше 7
C++ Если строка содержит больше пяти латинских "a",заменить все латинские и русские буквы строки следующими по алфавиту символами.
Если длина строки меньше заданной, то повторить ввод C++
C++ Вывод слов из файла длина которых больше N
C++ Определить длину введенной строки L, и если длина L четная, то удаляются 3 первых, иначе 3 последних символа
C++ Программа со строками. Определить длинну введенной строки L и если длина L кратна 3 удалит каждый третий символ
C++ Вывести на консоль те строки, длина которых меньше (больше) средней, а также длину.
C++ Если длина строки больше 10 - оставить первые 6 символов, иначе дополнить строку символами 'о'
Если среднее арифметическое чисел больше нуля, то результат записать в один файл, если меньше - в другой C++
C++ Определить длину введенной строки, и, если длина больше заданной, то удалить символы от a до z

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
21.02.2013, 21:23     EAccessViolation, если длина строки больше 14 #2
Потому что вот что говорит стандарт: 3.7.3.1/2
The allocation function attempts to allocate the requested amount of storage. If it is successful, it shall
return the address of the start of a block of storage whose length in bytes shall be at least as large as the
requested size
.
Поэтому ниже есть еще такое
Even if the size of the space requested is zero, the request can fail.
То есть даже на 0 может не хватить места, например.

Ну и еще
The effect of dereferencing a pointer returned as a request for zero size is undefined
В твоем случае, скорее всего, система отдала 16 байт (15 символов + '\0' строки)
VV_RIP
9 / 8 / 1
Регистрация: 05.02.2012
Сообщений: 105
21.02.2013, 23:21  [ТС]     EAccessViolation, если длина строки больше 14 #3
Хм ... а почему система несмотря на выделение только 16 байт, все равно может записать туда больше? Т.е. получается, что записать она может, но возникают проблемы при закрытии программы при освобождении памяти? Т.е. с одной стороны функция strlen(), например, видит реальный размер, но при закрытии все равно что-то недоудаляется? где-то утечка?
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
21.02.2013, 23:30     EAccessViolation, если длина строки больше 14 #4
а кто ей помешает? Ты же не можешь знать из какой кучи она достала эту память. Если ты под окнами, то система берет из кучи процесса (HeapAlloc(GetProcessHeap(), ...)), например; Обычно эта куча не ограничивается десятками байт. При выходе и проверке обнаруживается нарушение, о чем тебе и сообщается.

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

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

Кстати, отвлеченно от памяти, у тебя еще одна неприятность есть в коде
C++
1
2
3
4
5
    char *arr1 = new char[0];
    char *arr2 = new char[0];
....
    delete arr1;
    delete arr2;
Если ты используешь new [], то должен использовать delete [] для удаления.
VV_RIP
9 / 8 / 1
Регистрация: 05.02.2012
Сообщений: 105
23.02.2013, 23:46  [ТС]     EAccessViolation, если длина строки больше 14 #5
Ах да ... позабыл поставить квадратные скобки)
Да, это под Win, c++ builder.
Причем я заметил такую особенность, что, когда мы только создали переменную, там лежит только один символ '\0', а как только добавляем хоть один элемент, массив автоматом расширяется до 16, включая символ конца строки, конечно.
Проблема (т.е EAccessViolation) исчезает, только если мы ручками определяем размер массива.
Но тут вопрос: зачем тогда выделяется эта память, если при таком её использовании все заканчивается ошибкой?
Причем, если мы выделили память для 7 элементов и используем strlen, то он покажет 7, хотя на самом деле там ведь 16! И мы можем посмотреть содержимое этих 16 элементов. Видимо в памяти хранится ещё кучка дополнительной инфы, какие элементы массива доступны, а какие как бы и есть, но и их и использовать нельзя ... даже можно, но будет ошибка потом. Но на вопрос зачем это не отвечает ...
Yandex
Объявления
23.02.2013, 23:46     EAccessViolation, если длина строки больше 14
Ответ Создать тему
Опции темы

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