[英]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.