繁体   English   中英

有人可以向我解释为什么这是可能的吗?

[英]Can someone explain to me why this is possible?

int main ()
{
   char *strA = "abc";
   int tam_strA = strlen(strA);
   
   char strB[tam_strA];
   strB[0] = 'a';
   strB[1] = 'b';
   strB[2] = 'c';
   strB[3] = 'd';
   strB[9] = 'z';
   
   printf("%c", strB[9]);
   
   return 0;
}

它正常打印'z'。 为什么它不返回分段错误错误? 因为我试图访问一个不应该存在的索引,因为 strB 的大小(索引数量)等于等于 3 的 tam_strA。

另外,做char strB[strlen(strA)];有什么不同/问题吗? 反而?

C 语言没有阻止您访问无效 memory 的规范,也不保证分段错误。 唯一的 promise 是,如果您尝试访问无效的 memory,这将导致未定义的行为

分段错误是可能的结果之一,而不是唯一的结果。

也就是说,唯一的问题是

 char strB[strlen(strA)];

也就是说, strB的长度不足以保存strA中的内容,因为它将缺少一个字节来保存空终止符。 当然,按字节使用就可以了,但是如果您想复制内容(或与strA长度相同的任何内容)并将strB用作string ,您将跑过分配的 memory (没有 null终止符),调用未定义的行为。

访问不属于您的 memory 时,您只会遇到分段错误。 你拥有你的整个堆栈。 strB[9]在操作系统看来是一个有效的 memory 访问。 您不应该这样做的原因是因为编译器不知道您使用的是 memory,因此它可能决定将 memory 用于其他用途。 它还有助于提高可读性并最大限度地减少程序员的错误。 而且,该标准将未声明的 memory 的使用定义为未定义的行为,因此您不能安全地使用它。 声明一个像int x; (或数组)告诉编译器您将在x处使用 memory。

这实际上与这个问题有关: 为什么定义数组之外的第一个元素默认为零? . 阅读那里更详细的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM