C6001:使用单元化内存"str[i]"

C6001: using unititialized memory "str[i]"

本文关键字:str 内存 单元 C6001      更新时间:2023-10-16

程序运行良好,尽管拳头打印的数字始终是"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';

这并没有错,因为标准保证这适用于数字。请注意,类似的字符算术(臭名昭著的... - '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运行到< cnt(而不是<=(。

如果您采用我之前的建议来使用<vector><string>,那么有一种更好的方法来循环存储在其中的项目,即范围。


#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;
}

你从不初始化str[0],但你输出它。

问题就在这里:

...
if (ch <=57 && ch >=48) {
int a = ch - '0';
cnt++;
str[cnt] = a;
}
...

您过早地递增cnt,使str[0]未初始化。你应该做:

if (ch <=57 && ch >=48) {
int a = ch - '0';
str[cnt++] = a;
}

此外,您的for循环中确实存在问题;您应该从 0 开始,直到字符串中最后一个初始化的元素,该元素位于索引cnt - 1处。它应该是这样的:

for (int i = 0; i < cnt; i++) {
cout << str[i] << " ";
}

for (int i = 0; i <= cnt - 1; i++) {
cout << str[i] << " ";
}