реализация strcat

Я попытался реализовать strcat самостоятельно и нашел реализацию strcat в Wiki, например. .... но когда я его использую, возникает ошибка сегментации.

Что не так с кодом ниже?

char *
strcat(char *dest, const char *src)
{
    size_t i,j;
    for (i = 0; dest[i] != '\0'; i++)
        ;
    for (j = 0; src[j] != '\0'; j++)
        dest[i+j] = src[j];
    dest[i+j] = '\0';
    return dest;
}

person skydoor    schedule 21.03.2010    source источник
comment
Код вроде в порядке. Вы уверены, что используете его правильно? Какой код клиента?   -  person jpalecek    schedule 21.03.2010
comment
Добавьте проверку на то, что dest или src является нулевым.   -  person mpez0    schedule 22.03.2010
comment
В стандарте C библиотека может делать все, что ей заблагорассудится, когда любой из указателей равен нулю; поведение не определено. Законное неопределенное поведение включает в себя «разумную работу»; это также включает «сбой с дампом ядра» и «удаление всех файлов на машине, на удаление которых у вас есть разрешение». Не рискуйте — не вызывайте библиотечные функции с нулевыми указателями.   -  person Jonathan Leffler    schedule 22.03.2010
comment
Вопрос должен звучать так: Почему реализация strcat в Википедии неверна? Вы должны спросить об этом на странице обсуждения вики (en.wikipedia.org/wiki/Talk:Strcat< /а>). Кроме того, вероятно, ваш клиентский код (который может даже не существовать) сломан.   -  person Martin Wickman    schedule 22.03.2010
comment
Совершенно верно, но при повторной реализации библиотечной функции, особенно если она сообщает о нарушениях сегментации, проверка на нулевые значения и следование принципу наименьшего удивления кажутся уместными.   -  person mpez0    schedule 22.03.2010
comment
Это ужасная идея. Большинство недопустимых указателей не являются нулевыми, поэтому на практике это не помогает. И когда вы обнаружите нулевой указатель, что вы собираетесь с ним делать? Прервать программу? Потому что это произошло бы в любом случае.   -  person melpomene    schedule 05.08.2017


Ответы (5)


код в порядке.

Похоже, у вас проблема в коде вызова.

Вы не забыли выделить достаточно памяти для целевой строки?

person Pavel Radzivilovsky    schedule 21.03.2010
comment
Особенно для нулевого терминатора. - person SLaks; 21.03.2010
comment
+1, вероятно, OP вызывает строковую константу в качестве параметра назначения. - person Carl Norum; 21.03.2010

Я бы настоятельно рекомендовал использовать указатели, а не целочисленные индексы, из-за опасений целочисленного переполнения. Даже если size_t имеет то же количество битов, что и char *, вы добавляете индексы, а не указатели.

Думаю, это более или менее академично; если вы вызываете strcat() для многогигабайтных строк, у вас, вероятно, будут всевозможные проблемы.

Вот версия на основе указателя, для полноты картины:

char *
my_strcat(char *dest, const char *src)
{
    char *rdest = dest;

    while (*dest)
      dest++;
    while (*dest++ = *src++)
      ;
    return rdest;
}

Конечно, для возвращаемого значения rdest требуется еще один указатель, но я думаю, что это хороший компромисс.

Также обратите внимание, что вы не можете легально определить функцию с именем strcat() в обычном коде приложения; все это пространство имен (общедоступные функции с именами, начинающимися с str) зарезервировано для реализации.

person unwind    schedule 22.03.2010

dest должен иметь достаточно памяти для объединения в этой реализации. В этой реализации он должен быть выделен вызывающей стороной. Вы также должны быть уверены, что и dest, и src завершаются нулем. Если у dest недостаточно памяти, это перезапишет память, которая может быть использована чем-то другим.

person Michael Dean    schedule 21.03.2010

У меня работает нормально, проверял.

    #include "stdio.h"


    char *strcat(char *dest, const char *src)

    {

    size_t i,j;

    for (i = 0; dest[i] != '\0'; i++)

        ;

    for (j = 0; src[j] != '\0'; j++)

        dest[i+j] = src[j];

    dest[i+j] = '\0';

    return dest;

}


void main(void)

{

    char a[10]={"abc"}, b[10]={"def"};

    strcat(a,b);

    printf("%s",a);

    getchar();

}
person Siddiqui    schedule 22.03.2010

Выделите достаточно памяти для строки назначения.. т.е. по крайней мере (длина исходной строки + 1).

person Achuthananda MP    schedule 10.09.2013
comment
хм.. ничего нового в более ранних ответах, не так ли? - person kleopatra; 10.09.2013