简体   繁体   English

动态数组

[英]Dynamic Arrays

I'm just starting to learn C++ so excuse me for this simple question. 我刚刚开始学习C ++,请原谅我这个简单的问题。 What I'm doing is reading in numbers from a file and then trying to add them to an array. 我正在做的是从文件中读取数字,然后尝试将它们添加到数组中。 My problem is how do you increase the size of the array? 我的问题是你如何增加阵列的大小? For example I thought might be able to just do: 例如,我认为可能只能这样做:

#include <iostream>
using namespace std;

int main() {
    double *x;
    x = new double[1];
    x[0]=5;
    x = new double[1];
    x[1]=6;
    cout << x[0] << "," << x[1] << endl;
    return 0;
}

But this obviously just overwrites the value, 5, that I initially set to x[0] and so outputs 0,6. 但这显然只会覆盖我最初设置为x [0]的值5,因此输出0,6。 How would I make it so that it would output 5,6? 我怎么做到它会输出5,6?

Please realize that for the example I've included I didn't want to clutter it up with the code reading from a file or code to get numbers from a user. 请注意,对于我已经包含的示例,我不想使用从文件或代码读取的代码来混淆它以从用户获取数字。 In the actual application I won't know how big of an array I need at compile time so please don't tell me to just make an array with two elements and set them equal to 5 and 6 respectively. 在实际的应用程序中,我不知道在编译时我需要多大的数组,所以请不要告诉我只使用两个元素创建一个数组,并将它们分别设置为5和6。

Thanks for your help. 谢谢你的帮助。

You don't want to work with arrays directly. 您不希望直接使用数组。 Consider using a vector , instead. 请考虑使用vector Then, you can call the push_back function to add things to the end, and it will automatically resize the vector for you. 然后,您可以调用push_back函数将事物添加到最后,它会自动为您调整矢量大小。

#include <iostream>
#include <vector>

int
main() {
    double value;
    std::vector<double> values;

    // Read in values
    while (std::cin >> value) {
        values.push_back(value);
    }

    // Print them back out
    for (std::size_t i(0), len(values.size()); i != len; ++i) {
        std::cout << values[i];
    }
}

You should use a collection class to do this for you rather than managing it yourself. 您应该使用集合类为您执行此操作,而不是自己管理它。 Have a look at the "vector" class. 看看“矢量”类。 It's essentially a dynamic array that resizes automatically as required. 它本质上是一个动态数组,可根据需要自动调整大小。

In your situation you would use "vector" with the "double" type. 在您的情况下,您将使用“vector”和“double”类型。 You may also need to read up on templates in C++. 您可能还需要阅读C ++中的模板。

http://www.cplusplus.com/reference/stl/vector/ http://www.cplusplus.com/reference/stl/vector/

Or, if you don't want to use STL or another dynamic thing, you can just create the array with the correct size from the beginning: x = new double[2]; 或者,如果您不想使用STL或其他动态的东西,您可以从头开始创建具有正确大小的数组:x = new double [2];

Of course the problem there is how big to make it. 当然问题在于它有多大。 If you don't know, then you'll need to just create it "big enough" (like a hundred, or a thousand)... which, at some point, won't be big enough and it will fail in some random looking way. 如果你不知道,那么你需要创建它“足够大”(如一百或一千)......在某些时候,它将不够大而在一些情况下会失败随机看的方式。 So then you'll need to resize it. 那么你需要调整它的大小。 And once you get to that point, you'll wish you'd used the STL from the start, like the other answers are telling you to do. 一旦你达到这一点,你就会希望你从一开始就使用STL,就像其他答案告诉你的那样。

#include <iostream>
using namespace std;
int main() {
    double *x = new double[2];
    x[0]=5;
    x[1]=6;
    cout << x[0] << "," << x[1] << endl;
    return 0;
}

Here's an example though for good measure, so you can see the pattern: 这是一个很好的衡量标准,所以你可以看到模式:

#include <iostream>
using namespace std;

int main() {
    // Allocate some memory for a double array of size 1 and store
    // an address to the beginning of the memory in mem_address.
    double* mem_address = new double[1];

    // Assign 5 to the first element in the array.
    mem_address[0] = 5;

    // Save the address of the memory mem_address is currently
    // referencing.
    double* saved_address = mem_address;

    // Allocate some memory for a double array of size 2 and store
    // an address to the beginning of the memory in mem_address.
    mem_address = new double[2];

    // Copy over the 1 element from the first memory block
    // to the new one.
    mem_address[0] = saved_address[0];

    // Done with the old memory, so clean it up.
    delete [] saved_address;

    // Assign 6 to the second element in the new array.
    mem_address[1] = 6;

    // Print out the 2 elements in the new array.
    cout << mem_address[0] << "\n";
    cout << mem_address[1] << "\n";

    // Done with the new array memory now, so clean it up.
    delete [] mem_address;
}

If for some reason you don't have access to STL -- or want to learn how to do this yourself -- you could use an algorithm like this: 如果由于某种原因你无法访问STL - 或者想要自己学习如何做 - 你可以使用这样的算法:

Allocate your array as some arbitrary size, and remember how many elements are in it and how big it is: 将您的数组分配为任意大小,并记住其中有多少元素以及它有多大:

int *a = malloc(int * ARBITRARY_SIZE);
int size = 0;
int allocated = ARBITRARY_SIZE;

each time you add a new element, increase "size". 每次添加新元素时,请增加“大小”。 If size equals ARBITRARY_SIZE, multiply 'allocated' by 2, and reallocate the array. 如果size等于ARBITRARY_SIZE,则将'allocated'乘以2,然后重新分配该数组。 Either way, assign the new value to a[size]. 无论哪种方式,将新值分配给[size]。

void addElement(int value) {
  ++size;

  if (size == allocated) {
    allocated *= 2;
    a = realloc(sizeof(int) * allocated);
    a = new_a;
  }

  a[size] = value;
}

Note that your code above has at least one bug -- you aren't allocating enough space for x[1] in either case. 请注意,上面的代码至少有一个错误 - 在任何一种情况下,你都没有为x [1]分配足够的空间。

Also obviously in real code you'd check that the return from malloc & realloc isn't null. 显然,在实际代码中,您将检查malloc和realloc的返回值是否为空。

An array always needs a contiguous block of memory. 数组总是需要一块连续的内存块。 In a situation where you might need to resize the array later on, reallocation is probably the only solution. 在以后可能需要调整阵列大小的情况下,重新分配可能是唯一的解决方案。 This is what Moishe and Shadow2531 do above. 这就是Moishe和Shadow2531在上面做的事情。

The problem with reallocation is that it can be a costly operation. 重新分配的问题在于它可能是一项代价高昂的操作。 So if you need adding 5 more elements to a 5000 element array, you might end up copying all the 5000 elements across memory. 因此,如果您需要向5000个元素数组添加5个元素,最终可能会在内存中复制所有5000个元素。

Using a linked list instead can be considered for such a scenario. 相反,可以考虑使用链接列表来实现这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM