Можем ли мы присвоить массиву более длинную строку? - PullRequest
0 голосов
/ 08 декабря 2018

Прочитав в Интернете, я узнал, что следующие неопределенные поведения в C:

  1. Доступ к элементу вне массива

    char a2[4] = {'g','e','e','k','s'}; 
    printf("a2[4]:%d,%c\n",a2[4],a2[4]); //last index of a2 is 3
                                         //so a2[4] is undefined
    
  2. Наличие лишних элементов в списке инициализации массива

    int arr[3] = {1, 2, 3, 4, 5}; //size of arr is 3, but we specified 5 elements
                                  //undefined behavior
    

Я хочу спросить, является ли поведение в следующем связанном сценарии с указателями и строками неопределенным или нет:

  1. Назначение более длинной строки в массив символов:

    char arr[5] = "geeks"; //"geeks" contains 6 characters including `\0`
                           //but arr has size 5
    
  2. Доступ к дальнейшему индексу с указателем.

    char * arrptr = arr; //variable arr from point 1
    

    или

    char * arrptr = "geeks";
    

    и затем делать

    printf("%c",arrptr[7]); 
    

    Я считаю, что это, безусловно, должно быть неопределенным, поскольку индекс 7 не принадлежит ни к чему в текущем контексте.

Кто-нибудь может уточнить это или указать мне на соответствующий раздел в стандарте C?

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018
char arr1[5] = "geeks"; // extra '\0': ok
char arr2[4] = "geeks"; // extra 's' and '\0': error

Инициализация массивов символов с '\0' в качестве одного дополнительного элемента является особым случаем.См. C11 6.7.9p14 (выделено моё)

Массив символьного типа может быть инициализирован символьным строковым литералом или строковым литералом UTF-8, необязательно заключенным в фигурные скобки.Последовательные байты строкового литерала (, включая завершающий нулевой символ, если есть место или массив неизвестного размера), инициализируют элементы массива.

0 голосов
/ 08 декабря 2018
  1. char arr[5] = "geeks"; // ok

Само это утверждение не является UB.Он просто инициализирует массив символов (вместо строки).

Но когда вы начнете использовать его с чем-то вроде printf, он станет UB:

`printf("%s", arr);  // UB`

По вашему пункту 2) это, безусловно, UB, потому что вы получаете доступ за пределами

printf("%c",arrptr[7]); // UB

...