我们可以将更长的字符串分配给数组吗?

时间:2018-12-08 12:05:52

标签: c arrays string pointers

在线阅读后,我知道以下是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 :(得分:2)

char arr1[5] = "geeks"; // extra '\0': ok
char arr2[4] = "geeks"; // extra 's' and '\0': error

使用'\0'作为一个额外元素将char数组初始化是一种特殊情况。参见C11 6.7.9p14(强调是我的)

  

可以通过字符串文字或UTF-8字符串文字初始化字符类型的数组,还可以将其括在括号中。字符串文字的连续字节(,如果有空间,或者数组大小未知,则包含终止空字符;)初始化数组的元素。

答案 1 :(得分:1)

  1. char arr[5] = "geeks"; // ok

此语句本身不是UB。它只是初始化一个char数组(而不是字符串)。

但是当您将其与printf之类的东西一起使用时,它将成为UB:

`printf("%s", arr);  // UB`
  1. 对于您的观点2)肯定是UB,因为您正在访问越界

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