【问题标题】:Why can't initial length be 1 in a dynamically-allocated array?为什么在动态分配的数组中初始长度不能为 1?
【发布时间】:2012-11-24 00:56:14
【问题描述】:

假设我们从以下开始:

int *newArray = new int[1];

然后有类似的东西:

ifstream inputFile("File.txt");

Counter=0;

while (inputFile >> newValue)
{
    newArray[Counter] = newValue;
    Counter++
}

如果我尝试从文本文件中提取 100 行,程序最终会崩溃。但是,如果我使用过

int *newArray = new int[100];

原来,它不会崩溃。

如果是动态分配内存,为什么需要大于1的初始值?这对我来说毫无意义。必须定义任何超出诸如 1 或 10 之类的小数的初始长度,这违背了动态内存分配的全部目的......

编辑:这是给学校的,我们还不能使用向量。

【问题讨论】:

  • 因为当你只为一个'int'分配空间时,这就是你所得到的。当你想要更多时,你必须分配更多。内存分配的动态方面是您总是可以分配更多。并不是说它会自动增长。如果这就是你想要的,你想要一个 std::vector,或者一个可以根据需要分配更多内存的类。
  • @DavidO 很好地使用了“自动”这个词:)
  • “这是给学校的,我们还不允许使用向量。” -- 仅仅因为你被人为地限制了,就抱怨解决的问题有什么意义使用解决方案?
  • @Benjamin 不抱怨,只是澄清。
  • 谢谢大家的回答和cmets,你们很有帮助!

标签: c++ arrays visual-studio-2010 dynamic-memory-allocation


【解决方案1】:

该语言不会为您“动态分配内存”。您有责任分配和重新分配您的数组,以便它们的大小足以满足您的目的。

C++ 中“动态分配”的概念并不意味着内存会以某种方式自动为您分配。在这种情况下,“动态”一词仅表示新对象的参数和生命周期是在运行时(而不是编译时)确定的。动态内存分配的主要目的是:1)手动控制对象的生命周期,2)在运行时指定数组大小,3)在运行时指定对象类型。

第二点是什么让你这样做

int n = ...; // <- some run-time value
int *array = new int[n];

这对于非动态分配的数组是不可能的。

在您的示例中,如果最初的大小为 1,您可以分配一个数组。没什么不好的。但是您仍然有责任分配一个新的、更大的数组,将数据复制到新数组并在您的数组需要更多空间时释放旧数组。

为了避免所有这些麻烦,您应该简单地使用库提供的可调整大小的容器,例如 std::vector

【讨论】:

    【解决方案2】:

    它不是动态的,因为它可以动态调整自身大小。它是动态的,因为它的大小可以在运行时而不是编译时动态选择。 C++ 的主要理念之一是你不用为你不使用的东西付费。如果动态数组按您要求的方式工作,那将需要边界检查,这是我不需要的,所以我不想为此付费。

    反正问题用标准库解决了。

    std::vector<int> vec;
    ...
    while (inputFile >> newValue)
    {
        vec.push_back(newValue);
    }
    

    这样不是更好吗?您甚至不必跟踪大小,因为 vector 会为您跟踪它。

    如果您不能使用矢量,那么您还有很多工作要做。原理基本上是这样的。您保留 2 个额外的整数变量。一个表示您在数组中使用的值的数量,另一个表示您的数组的当前容量。当你的空间用完时,你会分配更多的空间。例如,这是一个穷人的非异常安全版本的向量:

    int size = 0;
    int capacity = 1;
    int array = new int[capacity];
    
    while (inputFile >> newValue)
    {
        if (size == capacity)
        {
            capacity *= 2;
            int * newArray = new int[capacity];
            for (int i=0; i<size; ++i)
                newArray[i] = array[i];
            delete [] array;
            array = newArray;
        }
        array[size++] = newValue;    
    }
    

    【讨论】:

    • @James:我不赞同和你一样的学习理念。我以身作则。况且,答案不只属于他。
    • @James:从技术上讲,家庭作业是的,但实际上并不是为了学分,所以在这方面不用担心:D 我们没时间了,所以她决定这将成为一项可选任务。
    【解决方案3】:

    您只为一个int 创建空间,但尝试存储多个,当然它会崩溃。即使您使用大小 100 创建它,当您尝试保存第 101 个值时它仍然会崩溃。

    如果您需要自动调整大小的容器,请查看std::vector

    #include <vector>
    
    std::vector<int> data;
    
    while (inputFile >> newValue)
    {
        data.push_back(newValue);
    }
    

    这将一直有效,直到您的进程内存不足。

    【讨论】:

    • @Sduibek 然后你必须做向量的工作,并跟踪动态分配的数组有多满。如果它已满,那么您需要动态创建一个更大的数组(oldSize * 2 应该可以正常工作),将内容从旧数组复制到新数组,然后删除旧数组。 File.txt 中是否有一行告诉您阵列需要多大?
    • @Sduibek 另外,如果他们正在测试您的动态内存分配技巧,那么他们可能打算让您使用链表?
    • 记住 std::vector 是用 C++ 编写的。如果您不能使用它,您可以创建自己的替代方案。
    • @James, DavidO:谢谢你们,这是替代品的好信息。
    猜你喜欢
    • 2016-05-16
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    • 2012-01-07
    相关资源
    最近更新 更多