2016-12-15 2 views
0

Итак, я видел несколько реализаций функции strcat с memcpy. Я понимаю, что это эффективно, так как нет необходимости выделять. Но как вы сохраняете переписывание содержимого исходной строки с результирующей строкой.Путаница о strcat с memcpy

Например позволяет бери:

char *str1 = "Hello"; 
char *str2 = "World"; 

str1 = strcat(str1, str2); 

Как убедиться, что в str2 не переписывается с содержанием полученного «HelloWorld» строки?

Кроме того, если строки не что иное, как массивы символов, а также массивы, предполагают, чтобы иметь фиксированный размер, то без перераспределения памяти если скопировать байты в массив, которые больше, чем массив, то это не то, что небезопасно?

+0

Пример, который * только * вызывается UB из-за перекрытия бы, вероятно, было более важно, что я думаю * * Ваш вопрос на самом деле, если вы понимаете, как 'strcat' работы (он * никогда * выделяет память). – WhozCraig

+0

Знаете ли вы, что такое указатель?Вы знаете, что такое String Literar? – Michi

+0

У нас только возник вопрос о реализации 'strcat()' в [Code Review] (http://codereview.stackexchange.com/questions/149812/strcat-implementation). OP использовал 'malloc()', поэтому было некоторое обсуждение этого подхода к стандартной библиотеке. –

ответ

1

Это не о небезопасно, это undefined behavior.

Прежде всего, вы пытаетесь изменить строковый литерал, который по своей сути вызывающей UB.

Во-вторых, относительно размера буфера назначения, цитируя man page (курсив мой)

strcat() функция присоединяетsrc строку в dest строку, переписав завершающий нулевой байт ('\0') в конце dest, а затем добавляет завершающий нулевой байт. Строки могут не перекрываться, и строка dest должна иметь достаточно места для результата. Если dest недостаточно велико, поведение программы непредсказуемо; [...]

+0

да, почему бы вам использовать memcpy, если он дает вам неопределенное поведение? почему бы просто не выделить новый массив с malloc и использовать там memcpy. –

+1

@ ng.newbie, это не так, как 'strcpy' предназначен для работы. Если это то, что * вы хотите сделать (динамическое распределение, две копии буфера и, надеюсь, когда-нибудь, 'free'call), здорово, но это не так, как' strcpy' спроектирован, поэтому он не шокирует он не ведет себя так. Если вы неправильно используете эту функцию, вы получите неопределенное поведение. Это не недостаток функции; это недостаток инженера, использующего его. – WhozCraig

1

Я понимаю, что это является эффективным, так как нет необходимости выделять.

Это неправильное понимание. Ни memcpy, ни strcat выделяет память. Оба требуют, чтобы вы передавали указатели, указывающие на достаточное количество действительной памяти. Если это не так, программа подвержена неопределенному поведению.

Опубликованный код подлежит непредсказуемое поведение для пары причин:

  1. str1 указует на строку буквальной, которая находится в части программы только для чтения.

  2. str1 Недостаточно памяти для хранения строки "HelloWorld" и завершающего символа нулевой последовательности.

+0

и 'str1' указывает на строковый литерал, так или иначе. –

+0

@SouravGhosh, да, это тоже. –