【发布时间】:2016-10-26 20:23:25
【问题描述】:
我正在尝试了解有关如何在 c 中定义“字符串”的基本知识。
char s[2];
scanf("%s", s);
printf("%s", s);
printf("sizeof s %d", sizeof(s));
我不是 c 程序员。我知道使用 scanf 获取用户输入存在问题,我什至没有检查它的返回值等。这只是为了了解有关声明字符串的一些基本知识。
鉴于上面的代码,如果我输入say 'helloworld' 会打印'helloworld'。好的。但我想通过说 char s[2] 我说的是像 's 是一个长度为 2 的数组,其中每个元素的类型都是 char'。
因此,我期待看到“他”被打印出来。不是“你好世界”。因为我的 s 数组只有 2 个字符的空间。
sizeof 仍然返回 2。但看起来我的数组已经增长到用户输入的大小。
发生了什么?
【问题讨论】:
-
它没有增长。您已经为
s分配了 2 个字符,这就是在堆栈上为它预留了多少内存。然而,scanf()只是接收到一个指向内存的指针。它无法知道分配了多少内存,所以它只是读取和存储,写入可能为其他东西设置的内存,直到完成。内存管理部分由您决定。这些类型的错误是许多“什么...?”的根源。调试时刻,因为它通常看起来像 else 被破坏了。 -
为什么他的scanf中没有&s?
-
您正在覆盖数组的边界,从而导致未定义的行为。你是正确的,你的数组只有 2 个
chars。你很幸运,写超过 2chars 并没有破坏其他东西。在另一台机器上或使用不同的编译器选项时,您可能不会那么幸运。此外,c字符串以 NULL (\0) 结尾,因此您需要在数组中添加一个额外的字符。 “helloworld” 的长度为 10chars,这意味着您需要一个char数组长度为 11chars 才能正确存储它。 -
不,阵列没有增长。通过输入长文本,您已经覆盖了数组外部的部分堆栈(或分配数组的任何内存)。当堆栈内存发生这种情况时,通常会导致崩溃或执行不需要的代码,尤其是当代码是远程访问服务的一部分时。
-
你暴露了
scanf中的缺陷,那就是它不是内存安全的。如果你在这里使用fgets,你会得到h作为你的回报(不要忘记空终止符)。
标签: c