Сравнение двух строковых литералов с использованием memcmp

Я сравнил два строковых литерала, используя 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 ответа

Решение

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

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

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

Да, поведение вашего кода не определено. Тем не менее, пока вы используете 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 можно найти здесь.

Другие вопросы по тегам