Сравнение двух строковых литералов с использованием memcmp - PullRequest
0 голосов
/ 02 мая 2018

Я сравнил два строковых литерала с помощью функции memcmp.

#include <stdio.h>
#include <string.h>

int main() 
{
  char str1[] = "abcd";
  char str2[] = "ab";

  if (memcmp(str1, str2, 4) == 0) 
  {
    printf("equal string\n");
  }
  return 0;
}

В приведенной выше программе str2 короче str1. Это означает, что строка str2 доступна вне границ.

Итак, это неопределенное поведение?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Да, поведение вашего кода не определено. Однако, если вы используете if (memcmp(str1, str2, 3) == 0) (обратите внимание, что количество байтов равно 3 вместо 4. Т.е. минимум два), поведение вашего кода будет приемлемым и правильным.

Поведение не определено, если доступ происходит после конца любого объекта, на который указывают lhs и rhs. Поведение не определено, если lhs или rhs является нулевым указателем.

В случае strcmp он останавливается, как только находит \0. Однако для memcmp

ошибочное предположение, что memcmp сравнивает побайтово и не смотрит на байты за пределами первой точки различия. Функция memcmp не дает такой гарантии. Разрешается читать все байты из обоих буферов, прежде чем сообщать о результате сравнения.

Итак, я бы написал свой код так:

#include <stdio.h>
#include <string.h>

#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))

int main() 
{
  char str1[] = "abcd";
  char str2[] = "ab";
  int charsToCompare = MIN(strlen(str1), strlen(str2)) + 1;

  if (memcmp(str1, str2, charsToCompare) == 0) 
  {
    printf("equal string\n");
  }
  return 0;
}

Более подробную информацию и анализ по memcmp можно найти здесь .

0 голосов
/ 02 мая 2018

Поведение вашего кода не определено. Стандарт C не требует, чтобы memcmp возвращался, как только известен результат; то есть он не обязательно должен возвращаться, когда \0 сравнивается с 'c', несмотря на то, что значение 'c' == '\0' равно 0 для любой кодировки символов, поддерживаемой языком. Стандарт также не определяет порядок, в котором должны выполняться лексикографические сравнения (хотя было бы непросто начать реализацию , а не с самого начала).

str2 относится к типу char[3]. Возможно, сделана попытка доступа к 4-му элементу.

Ссылка: http://en.cppreference.com/w/c/string/byte/memcmp

...