2014-12-10 2 views
0

Скажет, у меня есть код:Переполнение не обнаружено при записи нулевого символа в середине строки?

char* word = malloc (sizeof(char) * 6); 
strcpy(word, "hello\0extra"); 
puts(word); 
free(word); 

Это компилирует просто найти и Valgrind не имеет проблем, но есть на самом деле проблема? Похоже, я пишу в память, что я не владею.

Кроме того, отдельный вопрос, но когда я переполнить мой буфер с чем-то вроде

char* word = malloc (sizeof(char) * 6); 
strcpy(word, "1234567\0"); 
puts(word); 
free(word); 

Он печатает 1234567 и Valgrind делает поймать эту проблему. Каковы последствия этого? Кажется, он работает каждый раз. Пожалуйста, поправьте меня, если это не так, но из того, что я понимаю, возможно, что другая программа возьмет память мимо 6 и напишет в нее. Если это произойдет, будет ли печатание слова просто продолжаться вечно, пока он не встретит нулевого символа? Этот персонаж просто запутался для меня в изучении струн C.

+0

О, единственная реальная проблема - вы получите неприятный случай с NASAL DEAMONS. – IdeaHat

+0

'strcpy (word," hello \ 0extra ");' остановится после 6-го символа (терминатора), поэтому нет никаких проблем с этим надуманным примером. –

+0

Ваш второй вопрос: 'strcpy' скопирует все, что вы скажете, в пространство переполнения, если оно не вызывает ошибку сегмента. Независимо от того, что это сломает, зависит от того, что оно переписало. Просто предположим, что это что-то сломает. –

ответ

2

Первый зЬгсру нормально

strcpy(word, "hello\0extra"); 

Вы создаете char константу массива и передать указатель на strcpy. Все символы (включая первый \ 0) копируются, остальные игнорируются.

Но подождите ... У вас есть дополнительные символы. Это значительно сократит ваш раздел данных const. Может быть проблемой во встроенной среде, где флэш-пространство встречается редко. Но не существует проблемы времени выполнения.

0
strcpy(word, "hello\0extra"); 

Это справедливо, потому что второй должен быть параметр Я хорошо сформированная строкой и это потому, что у вас есть \0 в качестве 6-го символа, который формирует строку длины 5.

strcpy(word, "1234567\0"); 

Здесь вы доступ к памяти, которую вы не владеете/не распределяете, так что это нарушение прав доступа и может привести к сбою. (seg fault)

0

С вашего первого вызова strcpy, NUL вставлен в середину строки. Это означает, что функции, которые имеют дело с строк с нулевым завершением, будут считать вашу строку остановкой с первым NUL, а остальная часть вашей строки будет проигнорирована. Тем не менее, free освободит все это, и valgrind не сообщит о проблеме, потому что malloc сохранит длину буфера в таблице распределения, а free будет использовать эту запись, чтобы определить, сколько байтов освободится. Другими словами, malloc и free не предназначены для обработки строк с нулевым символом, поэтому NUL в середине строки не будет влиять на них. Вместо этого free определяет длину строки в зависимости от того, сколько вы выделили байт.

Во втором примере вы переполняете конец буфера, который был выделен malloc. Результаты этого не определены. Теоретически, память, которую вы пишете, могла быть выделена другим вызовом malloc, но в вашем примере с вашим буфером ничего не делается с памятью, поэтому она безвредна. Функции строковой обработки предполагают, что ваша строка заканчивается первым NUL, а не с концом буфера, выделенным malloc, поэтому вся строка распечатывается.

+0

Возможно, это только я, но это не кажется особенно ясным. 'malloc' и' free' не заботятся о том, что в памяти; 'free' освободит шесть байт malloced. 'strcpy' только пишет' hello \ 0' в 'word', поэтому' extra' будет существовать только в строковой таблице программы - он никогда не копируется нигде. – yellowantphil

0

В вашем первом вопросе уже есть несколько хороших ответов.О вашем втором вопросе о последствиях написания одного байта за концом вашей памяти malloced:

Сомнительно, что mallocing 6 bytes и запись 7 в него вызовут сбой. malloc любит выравнивать память на определенных границах, поэтому он вряд ли даст вам шесть байт в конце страницы, так что будет нарушение доступа в байте 7. Но если вы malloc 65536 байт и попробуйте написать мимо В конце этого может произойти сбой вашей программы. Запись в недействительную память работает много времени, что делает отладку сложной, потому что вы получаете случайные сбои только в определенных ситуациях.

Смежные вопросы