如何在运行时创建和增加数组的大小 C++.

How to create and increase the size of an array at runtime in C++

本文关键字:数组 C++ 增加数 增加 运行时 创建      更新时间:2023-10-16

我想创建一个数组,我只能在运行时知道其大小,然后在程序执行期间进一步增加该大小。
这是来自/r/dailyprogrammer 挑战,可以在这里找到 https://www.reddit.com/r/dailyprogrammer/comments/3twuwf/20151123_challenge_242_easy_funny_plant/
MSVisual 给了我错误 std::badd_array_new_length这意味着它在实例化数组时遇到问题?
我厌倦了经常从它工作的网站复制代码字母,而且我经常收到错误。Visual 是一个糟糕的学习C++平台吗?我应该尝试QT吗?

#include <iostream>
#include <string>
void main(int argc, char* argv[]) {
    int currentPlants = std::stoi(argv[2]), targetPeople = std::stoi(argv[1]), currentProduce = 0, week = 0;
    int * plants;
    plants = new int[currentPlants];
    for (int i = 0; i < currentPlants; i++) {
        plants[i] = 0;
    }
    if (plants == nullptr) EXIT_FAILURE;
    while (currentProduce < targetPeople) {
        currentProduce = 0;
        for (int i = 0; i < currentPlants; i++) {
            currentProduce += plants[i];
            plants[i]++;
        }
        if (currentProduce >= targetPeople) break;
        else {
            plants = new int[currentProduce];
            for (; currentPlants < currentProduce; currentPlants++) {
                plants[currentPlants] = 0;
            }
        }
        week++;
    }
    std::cout << week;    
}

您应该使用std::vector .

总结一下:

// Create an array of size 10    
std::vector<int> my_vector(10);
// Add '3' to my_vector
my_vector.push_back(3);
// Remove the last element
my_vector.pop_back();

这里的解释和示例:www.cplusplus.com/reference/vector/vector/

编辑 :构造对象时无需指定数组大小。

// Create an array    
std::vector<int> my_vector;

不能在运行时增加数组的大小。您可以创建一个新的更大的数组,并将旧数组的内容复制到新数组。

代码的问题在于,在第一次通过plants时,所有plants[x]都为零。您将所有这些加在一起并得到零 => currentProduce == 0 。然后,您尝试new plants[currentProduce aka 0]这是非法的。

您的第二个问题是,每次new时,您都会创建一个丢弃旧值的新数组; new创建一个数组,它对旧数组一无所知。

我使用 std::vector 重写了您的代码,它修复了崩溃但产生了一个无限循环,因为在第一次传递时,currentProduce变为零,因此数组被截断。

#include <iostream>
#include <string>
#include <vector>
int main(int argc, const char* argv_real[])
{
    const char* argv[] = { "programname", "5", "25" };
    int currentPlants = std::stoi(argv[2]), targetPeople = std::stoi(argv[1]), currentProduce = 0, week = 0;
    std::cout << "targetPeople = " << targetPeople
              << ", currentPlants = " << currentPlants
              << "n";
    std::vector<int> plants;
    // Option 1:
    // plants.resize(currentPlants);
    // Option 2:
    for (auto i = 0; i < currentPlants; ++i) {
        plants.push_back(0);
    }
    while (currentProduce < targetPeople) {
        std::cout << "cp: " << currentProduce
                  << ", tp: " << targetPeople
                  << "n";
        currentProduce = 0;
        // plantCount is a reference to plants[i] for each i
        for (auto& plantCount : plants) {
            std::cout << plantCount << ", ";
            currentProduce += plantCount;
            plantCount++;
        }
        std::cout << " cp: " << currentProduce << "n";
        if (currentProduce >= targetPeople)
            break;
        // Option 1:
            plants.resize(currentProduce);
        // Option 2:
        //  while (currentPlants < currentProduce) {
        //      plants.push_back(0);
        //  }
        week++;
    }
    std::cout << week;    
}

现场演示:http://ideone.com/xGpoF6

除了使用 std::vector 之外,您需要在堆上分配一个新数组,复制内容并删除旧数组。然后将int*指向新分配的阵列。

这在技术上不会改变数组大小,但访问对象的人会看到它好像正在改变。

这很危险:

int * plants;
plants = new int[currentPlants];
for (int i = 0; i < currentPlants; i++) {
    plants[i] = 0;
}
if (plants == nullptr) EXIT_FAILURE;

这是发生的事情(如果你幸运的话):

  • 程序尝试创建一些内存,如果不能,则返回 nullPTR
  • 然后,程序在循环中使用内存,即使返回了 nullptr。(如果返回nullptr,这将导致程序崩溃,静默损坏内存,因此您得到错误的结果或以其他方式执行您不想要的操作)
  • 然后,程序检查是否返回了 nullPTR。

如果你运气不好,编译器会进行时间旅行并摧毁整个宇宙。 我不是在开玩笑,看看:

  • https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=633
  • 导致时间旅行的未定义行为