Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.08.2014, 18:26   #1
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
Вопрос Мусор (или определённое неопределённое)

Здравствуйте, уважаемые программисты! Приходилось ли Вам копаться в "мусоре"? Мне приходилось.
Началось всё с того, как мне захотелось написать собственную реализацию strcat() и strlen() (разумеется в собственном пространстве имён) и я столкнулся с следующей проблемой.
В программе, тестирующей эти функции я объявил три строки:
Код:
char str1[80] = "Hallo!";
char str2[] = " How are you?";
char str3[80];
Как видите, первые две строки тут же инициализированы, а третья - нет (она вводится с клавиатуры).

Вот так я реализовал strcat:
Код:
void strcat(char* str1, const char* str2)  {
	int pos = strlen(str1);
	const char* q = str2;
	while (*q++) str1[pos++] = *(q - 1);
}
Вот strlen:
Код:
int strlen(const char *str) {
	const char* q = str;
	while (*q++);
	return q - str - 1;
}
Перед определением функций есть прототипы, так что, функции видят друг друга с этим проблем нет.
Для первых двух строк strcat сработала как надо, но когда я применил её к третьей:
Код:
strcat(str3, str2);
я узнал, что такое "мусор".
Оказалось, что str3 не содержит ни одного "завершающего нуля"! При объявлении, 3-я строка содержит 80 значений -52, беззнаковое представление которых есть 204 в ASCII это русская 'M' или '╠'. При в воде в строку str3 n символов (n<80), первые n 'М' заменяются на символы, введённые с клавы, а остальные не меняются! А при инициализации первой строки все "оставшиеся" символы равны 0, поэтому с ним проблем нет. В strcat пришлось дописать
Код:
str1[pos] = '\0';
Или нужно было объявить str3 как нуль-строку
Код:
	char str3[80] = "";
Теперь всё работает, но остались вопросы.

Итак, как я понял, значение -52 для char есть ничто иное как "мусор". Эксперимент даёт следующие результаты для "мусора" других типов:
Цитата:
char: -52 'М' | short: -13108 | int: -858993460 | float: -107374176. | doule: -9.2559631349317831e+061
Как я понял здесь int и double расширяются до long-значений, т.к. для long и long double "мусор" идентичен соответствующим значениям для int и double.
Внимание! Bопросы:
1) Почему "мусор", который как я читал и считал должен иметь неопределённый результат имеет вполне определённые отрицательные значения?
2) Почему они именно такие?
3) Зависят ли эти значения от модели процессора, компилятора ОС или ещё чего?

Очень надеюсь на ответы. Заранее благодарен.

Последний раз редактировалось Haric_110; 06.08.2014 в 18:29.
Haric_110 вне форума Ответить с цитированием
Старый 06.08.2014, 19:33   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
значение -52 для char есть ничто иное как "мусор"
Чего это так? -52 это код символа М он же СС в 16-ти ричной кодировке.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.08.2014, 19:51   #3
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Да, я согласен. Но почему неинициализированный символьный массив состоит из символов 'M'?
Haric_110 вне форума Ответить с цитированием
Старый 06.08.2014, 19:58   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

М.м.м. Я может глупость сморожу, но по моим догадкам это такая себе защита от... переполнения что ли... ССh это опкод прерывания INT3. Отладочное прерывание
Может загрузчик вставляет этот код, чтоб в случае нарушения доступа к памяти и попытка выполнить байты строки как код привела к вызову отладчика, типо сигнализируя - Ахтунг, что-то не так.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.08.2014, 20:07   #5
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Возможно. Тогда для других типов данных это тоже защита от антипереполнения?

Да, действительно, я проверил другие числа. Если учитывать память которую занимают объекты этих типов, то эти числа для каждого из них состоят из ССh. СС на каждый байт.

Спасибо, Stilet!

Последний раз редактировалось Stilet; 06.08.2014 в 20:27.
Haric_110 вне форума Ответить с цитированием
Старый 06.08.2014, 20:27   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Наздоровье )
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.08.2014, 20:40   #7
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Так это и есть то, что называют "мусором" или нет?
Haric_110 вне форума Ответить с цитированием
Старый 06.08.2014, 20:48   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Ну не похоже. Если это ставит менеджер памяти, то видимо это не мусор. Другое дело, если ты обьявил переменку, но не присвоил ей значение, то по факту ее адрес может указывать на память занятую кем-то до этого, и этот кто-то не обнулил после себя занятые ячейки. В результате код
Код:
int m; printf("%d",m);
может показать так называемый "мусор" - значение, иставленное в памяти, куда уже поместили твою переменную кем-то, кто занимал эти ячейки до твоей программы.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.08.2014, 20:49   #9
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Нет, это Debug сборка, где все переменный инициализируются в 0xCC.
В Release сборке содержимое будет случайным.
Но в принципе да, это тоже можно считать мусором.
waleri вне форума Ответить с цитированием
Старый 06.08.2014, 21:35   #10
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Хорошо. Я понял. Будем считать, что в моём случае это не мусор, а пометка переменной "Пусто" - защита от антипереполнения, которая работает при Debug-отладке.
Спасибо!
Haric_110 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Dbgrid запрет на редактирование строки через определённое время spotip Компоненты Delphi 11 30.04.2014 14:53
вставка нужного числа в определённое поле программы Cai_i_iok Помощь студентам 8 06.04.2013 11:29
Определённое значение из доступных данных Sprat PHP 2 29.03.2013 20:13
определённое место сайта+txt новости Too Работа с сетью в Delphi 5 22.10.2011 21:23
цикл на определённое время Nitrino Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 3 12.01.2010 13:57