2017-01-25 18 views
0

От C стандарт:Что такое перекрытие строк в соответствии со стандартом C?

7.21.2.4 strncpy функция

Если копирование происходит между объектами, которые перекрывают друг друга, поведение не определено.


Что перекрывается?

Ясно, что он перекрывается, когда начало целевой строки пересекает конец исходной строки.

Но перекрывается ли это в следующем примере?

const char* dateConst = "2017-01-25"; 
char* date = malloc(16); 
strcpy(date, dateConst); 

strncpy(date+4, date+5, 2); 
strncpy(date+6, date+8, 3); 

printf("%s\n", date); 

Выход: 20170125

Если strncpy только copyes символы полукокса на гольца, как это в this implementation, не должно быть никаких проблем.

+1

Хотя это стандарт C, который определяет поведение 'strncpy', вы, кажется, компилируете C++ .. – StoryTeller

+0

' strncpy' является опасной функцией, и ее следует избегать. Он никогда не предназначался для использования с нулевыми завершенными строками. Вместо этого используйте 'memcpy' или' strcpy'. – Lundin

+0

@ Lundin Вау, я этого никогда не слышал. Почему вы рекомендуете 'strcpy' над' strncpy'? (Я всегда слышал наоборот). –

ответ

1

Если strncpy просто копирует символы char char, как в этой версии , проблем не должно быть.

Это как раз проблема. В стандарте не указывается, какой должна функционировать функция, но какой результат должен дать, и в то же время указать, что если есть какой-либо перекрытие, то получается UB, что делает кодеры бесплатными для использования независимо от подхода как .

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

В конце концов вы можете использовать функцию memmove, которая явно позволяет перекрывать или записывать вашу собственную функцию с перекрытием.

1

strncpy не может быть реализован каким-либо конкретным способом. Стандарт C только диктует контракт API, которому он должен следовать. Любая реализация может решить сделать перекрытие без проблем, но это не обязано делать по стандарту.

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

+0

'memcpy' не допускает перекрытия,' memove' позволяет перекрывать. Вы можете исправить ответ. –

+0

@Frankie_C - Я не знаю, что я сказал, и сказал, что я имел в виду. 'strncpy' может иметь неопределенное поведение в случае перекрытия, поэтому ** может ** использовать' memcpy' (в возможной реализации библиотеки) и ставить вину на пользователя, если что-то накладывается. – StoryTeller

+0

Извините, я неправильно понял. Если вы согласитесь, я удалю все комментарии. –