exponenta event banner

Правило AUTOSAR C++ 14 A27-0-4

Не должны использоваться строки в стиле C

Описание

Определение правила

Не должны использоваться строки в стиле С.

Объяснение

Базовый символьный массив, в котором хранится строка в стиле Си, имеет множество недостатков, таких как:

  • При выполнении операций со строкой, требующих нетривиальных манипуляций с памятью, необходимо явно обрабатывать выделение и освобождение памяти.

  • Не всегда ясно, char* указывает на один символ или на строку в стиле C.

  • Можно случайно преобразовать массив в необработанный указатель при передаче его по значению или указателем на функцию, что приводит к потере информации о размере массива (распад массива). Например, в этом фрагменте кода func печатает размер указателя на первый символ cString (8), в то время как фактический размер cString составляет 6.

    void func(char *c){ //function takes array by value
      cout << sizeof(c);
    }
    
    void main(){
      char cString[]{ "pizza" }; //Size is 6 (5 characters + null terminator)
      func(cString); // Size is 8 (size of char*)
    }

Вместо этого используйте std::string для хранения последовательности символов. Класс обрабатывает назначения и освобождения и создает экземпляр объекта, который можно безопасно передать функциям. Класс также имеет встроенные функциональные возможности для управления строкой, такие как итераторы.

Внедрение Polyspace

Polyspace ® помечает использование:

  • Указатели на символ (char*) и массивы символов (char someArray[]).

  • Указатели и массивы символов с квалификатором типа, например volatile или const. Например, char const*.

  • Указатели и массивы типа wchar_t, char16_t, и char32_t.

Если в исходном коде имеется объявление функции и ее определение, Polyspace помещает нарушение в определение функции. Например:

const char* greeter(void);
//....
const char* greeter(void){ //Non-compliant
  return "Hello"; 
}

Polyspace не помечает использование:

  • Указатели или массивы signed или unsigned char. Например, signed_c и unsigned_arr не помечены в этом фрагменте кода:

    signed char* signed_c;
    unsigned char unsigned_arr[2048];

  • Буквенные строки. Например, возвращаемое значение greeter() не помечен в этом фрагменте кода, но использование const char* в первой строке отмечается:

    const char* greeter(void){ //Non-compliant
      return "Hello"; // Compliant
    }

  • Параметры main().

Поиск неисправностей

Если вы ожидаете нарушения правила, но не видите его, обратитесь к разделу Нарушения стандартов кодирования не отображаются.

Примеры

развернуть все

#include<iostream>
#include <string>
#include<cstring>

char* sub_c_str(   //Non-compliant
    const char* str1, const int delim)  //Non-compliant
{
    size_t index {strlen(str1)};
    if (strchr(str1, delim)) {
        index = (size_t)(strchr(str1, delim) - str1);
    }
    char* p = (char*) malloc(index + 1); //Non-compliant
    //memory leak if p is not freed by caller
    strncpy(p, str1, index);
    return p;

}

std::string sub_str(std::string const str2, const char delim)
{
    return str2.substr(0, str2.find(delim));
}

int main()
{
    const char str1[] { "rootFolder/subFolder"}; // Non-compliant
    std::cout << sub_c_str(str1, '/') << std::endl;

    std::string const str2 { "rootFolder/subFolder" };
    std::cout << sub_str(str2, '/') << std::endl;
    return 0;
}

В этом примере функция sub_c_str возвращает подстроку строкового параметра стиля C str1 до, но не включая первый экземпляр delim. Возвращаемый тип и первый параметр sub_c_str оба являются несовместимыми указателями на символ. Указатель p, которая хранит подстроку, также несовместима. Обратите внимание, что если вы не освободите память, выделенную p перед окончанием программы это приводит к утечке памяти.

Функция sub_str использует преимущества std::string класс для выполнения той же операции, что и sub_c_str. Класс обрабатывает выделение и освобождение памяти. Класс также имеет встроенные функциональные возможности (find и subst) для выполнения обработки строки.

Проверить информацию

Группа: Библиотека ввода/вывода
Категория: Обязательно, Автоматизировано
Представлен в R2021a