c++ - 固定大小的 C++ 数组获取垃圾值
问题描述
我试图将字符串循环旋转 1 个班次。这是简单的代码:
#include <bits/stdc++.h>
using namespace std;
int main() {
string s = "1010";
char a[s.length()];
for (int i = 0; i < s.length() - 1; i++) {
a[i] = s[i+1];
}
a[s.length()-1] = s[0];
std::cout << a << '\n';
std::cout << strlen(a) << '\n';
}
当我运行此代码时,我得到以下输出:
aditya@aditya-Inspiron-3558:~/miscCodes$ ./a.out
0101�
6
我的数组的长度如何变化?由于垃圾值?
解决方案
可变长度数组 (VLA)不是标准 C++ 的一部分。阅读更多内容,为什么可变长度数组不是 C++ 标准的一部分?
但是,假设您使用了允许它们的编译器扩展,那么问题是您在这里使用了 C 函数:
std::cout << strlen(a) << '\n';
它需要一个 C 字符串,这意味着一个以NULL 结尾的字符串。
这意味着您应该使您的数组足够大以容纳 NULL 终止字符,如下所示:
char a[s.length() + 1];
因为string::length()
将为字符串“1010”返回 4。这意味着 C 字符串应该是这样的:“1010\0”,即实际字符串,附加 NULL 终止字符。因此,您需要一个大小为 5 的数组来存储该字符串。
一个简单的解决方法是:
char a[s.length() + 1] = {0};
这将 NULL 初始化数组的每个单元格。然后,您将用字符覆盖它的每个单元格,除了最后一个单元格,专门为 NULL 终止符保留。
另一种方法是仅将 NULL 终止符分配给字符串的最后一个单元格,例如a[s.length()] = '\0';
. 注意s.length()
现在是数组最后一个元素的索引。
标准 C 字符串函数(如strlen()
)依赖于 NULL 终止字符来标记字符串的结尾。在没有那个重要角色的情况下,他们不知道何时停止,因此访问超出了他们打算访问的点的内存。
这会调用未定义行为(UB),它在您的计算机中使用垃圾值访问内存。
推荐阅读
- hyperledger-fabric - 订购者是否存储所有区块链?
- angular - 可观察对象字段作为 Firestore 中的查询参数
- python-asyncio - 测试返回协程的函数包装器
- java - cmd中的scipt在java文件中创建包目录
- python - 具有共享输出的python多处理
- javascript - 从 json 数据创建表
- javascript - 如何将 onClick 事件设置为延迟加载的图形或图像元素
- arrays - Excel VBA 比较部分行并删除重复项
- python-3.x - 如何在 Pycharm 中设置 shell 提示符
- python - 将循环添加/附加到另一个循环的末尾