AUTOSAR C++14 Rule A27-0-4

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

Описание

Управляйте определением

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

Объяснение

Базовый символьный массив, который хранит строку 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 (char someArray[]).

  • Указатели на и массивы char со спецификатором типа, такие как 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