c++ - C6001:使用未初始化的内存“str[i]”
问题描述
该程序运行良好,尽管第一个打印的数字始终是“3452816845”。我尝试通过在定义数组时添加大括号或给它 NULL 值来初始化“str [i]”,但是第一个打印的数字总是“零”,然后它才会打印我输入的内容。请看下面:
#include <iostream>
using namespace std;
int main() {
unsigned* str = new unsigned[1000];
int cnt = 0;
char ch;
int a;
cout << "Please enter text: ";
do {
cin.get(ch);
if (ch <=57 && ch >=48) {
int a = ch - '0';
cnt++;
str[cnt] = a;
}
} while (ch != '\n');
cout << "The entered numbers are: ";
for (int i = 0; i <= cnt; i++) {
cout << str[i] << " "; // here is where the error appears
}
delete[] str;
return 0;
}
解决方案
不要using namespace std;
。特别是不在标题中,但也尽量不在普通.cpp
文件中使用它。调试代码更方便,该代码明确地告诉您标识符来自哪个命名空间,而该标识符正被使用。
unsigned* str = new unsigned[1000];
自从 C++11 出现以来,这样的“裸”内存分配是不受欢迎的,在这里绝对没有必要。
- 您可以只使用静态数组 (
unsigned str[1000];
)。 - 您可以使用智能指针(
auto str = std::make_unique<char[]>(1000);
)。 - 最佳选择,使用 C++ 容器,例如
<vector>
,<string>
或 (如果开销真的困扰您)<array>
。
if (ch <=57 && ch >=48) {
int a = ch - '0';
不要在代码中使用“幻数”。如果您想知道输入的字符是否为数字,请使用isdigit
,它更具表现力,甚至适用于其数字可能位于代码表中不同位置的非 ASCII 编码。
int a = ch - '0';
这没有错,因为标准保证这适用于 digits。请注意,类似的字符算法(臭名昭著的... - 'a'
)是不受欢迎的,一旦你离开严格的 ASCII-7 编码领域,它就会中断。
cnt++;
str[cnt] = a;
C/C++ 从零开始计数。您刚刚未初始化数组中的第一项。后增量的美妙之处在于您可以在使用索引的地方进行操作,即str[cnt++] = a;
.
for (int i = 0; i <= cnt; i++)
cout << str[i] << " "; // here is where the error appears
}
很C,也错了。您没有初始化str[0]
,因此通过该循环的第一轮访问未初始化的内存。如果您已初始化str[0]
(cnt
仅在将其用作索引后才递增),i <= cnt
则将超出您写入的内容一项str[]
,再次访问未初始化的内存。循环应该从0
to < cnt
(not <=
) 运行。
如果您接受我之前的建议来使用<vector>
or <string>
,那么有一个更好的方法来遍历存储在其中的项目,即range-for。
#include <iostream>
#include <vector>
int main()
{
char ch;
std::vector< int > digits;
std::cout << "Please enter text: ";
do
{
std::cin.get( ch );
if ( std::isdigit( ch ) )
{
digits.push_back( ch - '0' );
}
} while (ch != '\n');
std::cout << "The entered numbers are: ";
for ( auto & i : digits )
{
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
推荐阅读
- c# - VBA-如何选择具有值的列单元格
- python - 带有标签的用户搜索引擎 - Django - Python
- python - 比较两个df并删除唯一值
- r - 绘图中的自动编号面板
- intel-oneapi - 无法使用 dpct 工具迁移简单的 CUDA 矢量添加示例。致命错误:找不到“helper_cuda.h”文件
- vue.js - 我的 Vue 模态有效,但未应用过渡样式
- mongodb - 如何通过 mongoose 删除 mongoDb 中的特定字段
- asp.net-core - Blazor WASM httpcontext 替代方案
- windows - 是否可以使用 netcat 将文件发送/exfil 文件到另一个外部网络上的机器?
- heroku - Heroku postgres 可以回滚到哪个时间?