Возможность сбоя strcat? - PullRequest
       2

Возможность сбоя strcat?

1 голос
/ 12 января 2010

Есть ли вероятность, что strcat может когда-нибудь потерпеть неудачу?

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

Я только что упомянул strcat в качестве примера. Но этот вопрос относится ко многим функциям, связанным со строками и памятью (например, memcpy и т. Д.). Я просто хочу узнать причину некоторых из этих, казалось бы, «всегда успешных» функций, имеющих возвращаемые типы.

Ответы [ 5 ]

10 голосов
/ 12 января 2010

Возвращение указателя на целевую строку позволяет легко использовать выходные данные следующим (возможно, не очень умным) способом:

int len = strlen(strcat(firstString, secondString));
3 голосов
/ 12 января 2010

Большинство из них возвращаются ко времени, когда C не включал 'void', поэтому не было никакого способа указать, что у него нет возвращаемого значения. В результате они указали, что они возвращают что-то , даже если это было довольно бесполезно.

2 голосов
/ 12 января 2010

Неявный контракт этих функций заключается в следующем: если вы передадите указатели на допустимые строки, то функции будут работать так, как объявлено. Передайте NULL-указатель, и функция может делать что угодно (обычно она вызывает SIGSEGV). При условии, что аргументы являются действительными (то есть указывают на строки), используемые алгоритмы не могут потерпеть неудачу.

1 голос
/ 12 января 2010

Вот довольно стандартная реализация strcat из OpenBSD:

char *
strcat(char *s, const char *append)
{
        char *save = s;

        for (; *s; ++s);
        while ((*s++ = *append++) != '\0');
        return(save);
}

Пока входные данные, переданные ему, действительны (т. Е. append правильно завершен и s достаточно велик, чтобы объединить его), это не может действительно дать сбой - это простая манипуляция памятью. Эта память полностью находится под контролем вызывающей стороны.

Возвращаемое значение здесь можно использовать для объединения цепочек, например:

strcat(strcat(s, t1), t2);

Хотя это вряд ли эффективно ...

1 голос
/ 12 января 2010

Я всегда игнорировал возвращаемые типы (интересно, кто их использует), до сегодняшнего дня я видел это в glibc-2.11 (скопировано точно из исходного файла), и все стало намного яснее:

wchar_t *
wcsdup (s)
     const wchar_t *s;
{
  size_t len = (__wcslen (s) + 1) * sizeof (wchar_t);
  void *new = malloc (len);

  if (new == NULL)
    return NULL;

  return (wchar_t *) memcpy (new, (void *) s, len);
}

Это облегчает написание меньшего количества кода ("цепочка", я так думаю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...