【问题标题】:C++ issue with new char[]新字符 [] 的 C++ 问题
【发布时间】:2024-01-22 12:44:01
【问题描述】:

有人可以向我解释一下,当我只要求 3 个时,为什么 char tab[] 中还有 4 个额外的插槽?如何摆脱它们?我在 Visual Studio 2017 中编码。编辑:第一个程序非常基础,并没有显示我的意图。所以,有一个扩展的。

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int i, n;
    vector<char> input;
    char chp;
    cout << "Enter a expression" << endl;
    while (1)
    {
        cin.get(chp);
        if (chp == '\n') break;
        input.push_back(chp);
    }
    n = input.size();
    char* tab = new char[n] {};
    for (i = 0; i < n; i++)
    {
        tab[i] = input[i];
    }
    int l = strlen(tab);
    for (int i = 0; i < l; i++) 
    {
        cout << "tab[" << i << "] is " << tab[i] << endl;
    }
    cin.get();
}

控制台窗口的结果类似,当我输入“3+3”时

tab[0] 是 3
tab[1] 是 +
选项卡 [2] 为 3
tab[3] 是 ř
tab[4] 是 ř
tab[5] 是 ř
tab[6] 是 ř

这仍然不是完整的程序(完整的程序是一个计算器,可以计算任何数学表达式,而且要长得多)。我很久以前在 C 中写过,在 C 中动态数组不是这样的问题。

另外,多维数组呢?字符串也可以成为他们的解决方案吗?

【问题讨论】:

  • tab 指向一组未初始化的charstrlen不返回数组的大小,它取决于它的内容。
  • en.cppreference.com/w/cpp/string/byte/strlen: 如果str指向的字符数组中没有空字符,则行为未定义。
  • 当你使用std::stringstd::vector 时,这种错误就更难犯了
  • 只要使用std:string 就开心了。
  • @PiotrGruchalski 作为一个经验法则:除非您 100% 确定必须这样做,否则不要尝试在 c++ 中自己管理内存分配。只需使用标准库容器和智能指针。你自己不太可能做得更好。

标签: c++ char new-operator dynamic-tables


【解决方案1】:

有人可以向我解释一下,为什么 char tab[] 中还有 4 个额外的插槽,而我只要求 3 个?

没有。该数组只有 3 个元素。

问题是您的数组元素具有不确定的值。由于将指向不确定值数组的指针传递给strlen,您的程序的行为是未定义的。

解决方案:初始化您的阵列。此外,根据strlen 的要求,对其进行初始化,使其包含一个空终止符:

char* tab = new char[3]{'a', 'b', '\0'};

作为空终止的替代方法,不要使用strlen 来获取长度。您已经知道该数组包含 3 个元素。但是在将它们插入输出流之前,这些值仍然必须进行初始化。

附:不要忘记删除您分配的内存:

delete[] tab;

【讨论】:

  • 如果数组的大小为 3,则它应包含的最长以空字符结尾的字符串为 2。因此,使用 3 并不能完全替代 strlen。编辑:虽然我同意它的初衷似乎是检查数组的每个字节,所以虽然这与原始代码有不同的行为,但它可能是 OP 想要做的。
  • 问题是,我不知道会有多少元素。 3 只是举例。所以初始化没有帮助。
  • @PiotrGruchalski 如果您不知道,请按照其他建议使用std::string。与动态分配的字符数组相反,std::string 对象的容量可以增长。
  • @PiotrGruchalski 事先不知道元素的数量不会阻止初始化。
最近更新 更多