关于C ++结构中数组的初学者问题

时间:2011-06-17 23:37:11

标签: c++ arrays struct

我想创建一个结构,并将其作为数组在其他结构中使用。我的问题是我不知道我想分配多大的数组,我只会知道我在一个函数中。我的意思是我想使用[]而不是预定的常量,比如10000。

我认为,如果你看一下我的代码,那将是不言自明的。你能帮我解决一下这段代码的工作原理吗?此外,如果你能告诉我我所询问的主题的名称是什么(它是动态数组吗?)以及我在哪里可以找到关于这个主题的文章/教程,它会对我有所帮助。

以下是我在思考结构中数组的方法时的代码。

#include <iostream>

using namespace std;

struct keyframe {
    bool a;
    int b;
    int c;
};


struct keyframe_file {
    const int num_views;
    const int num_keyframes;
    keyframe keyframes[];
};


int main() {

    keyframe_file my_file;

    my_file.num_views = 1;
    my_file.num_keyframes = 6;

    my_file.keyframes = new keyframe[my_file.num_keyframes];

    my_file.keyframes[0].a = true;
    my_file.keyframes[0].b = 5;
    my_file.keyframes[0].c = 9;

    return 0;

}

7 个答案:

答案 0 :(得分:5)

使用std::vector

struct keyframe_file {
    const int num_views;
    const int num_keyframes;
    std::vector<keyframe> keyframes;
};

int main() {
    keyframe_file frame;
    frame.keyframes.resize(...);
}

答案 1 :(得分:0)

您的代码几乎是正确的,除了两件事:

  1. keyframes必须是keyframe*而不是keyframe[]
  2. 您忘记了delete您分配的内存

答案 2 :(得分:0)

那是不完整的类型。在C ++中,必须为数组提供大小,并且必须在编译时自己知道大小。

您正在使用new,您应该使用指针

struct keyframe_file {
    const int num_views;
    const int num_keyframes;
    keyframe *keyframes;
};

std::vector<keyframe>仍然是更好的选择,正如@DeadMG已经建议的那样。

顺便说一下,前两个成员在结构中是const,这意味着,他们不能 分配值,就像你在做的那样你的代码。必须使用您希望它们保留的值初始化。这意味着,现在使用vector,你需要包含一个构造函数来初始化结构,因为结构不再是一个POD。

struct keyframe_file {
    const int num_views; //const member
    const int num_keyframes; //const member
    std::vector<keyframe> keyframes;

    keyframe_file(int nviews, int nkeyframes) 
    : num_views(nviews), num_keyframes(nkeyframes), keyframes(nkeyframes){}
};


keyframe_file my_file(1,6); //done!

答案 3 :(得分:0)

如果它适合您的目的,STL容器(std::vector)很容易成为最佳选择之一 - 您需要担心的内存管理越少越好。

在任何情况下,请查看上面发布的结构定义Nawaz - 这正是应该如何。 C ++中的动态数组只是指针。但是,您已经在代码中正确分配了内存,但是您还没有释放它(因此它正在泄漏)。由于您已分配new [],因此您需要

delete [] my_file.keyframes;

为了正确释放内存。

调整大小是另一个问题:使用智能实现,数组大小调整可以是一个分摊的O(1)操作,这很好。调整大小时,它总是需要你O(n),因为你需要将所有元素复制到一个不同大小的新数组中,但是如果你这样做了一半,它就会变成O(1)。也就是说,每次需要调整大小时,数组加倍。这是一个非常简单的例子

void resize()
{
  if(numOfElementsInArray == sizeOfArray)
  {
    ArrayType * arr = new ArrayType[sizeOfArray*2]; // Allocate a double size array
    for(int i=0;i<sizeOfArray;++i)
      currentArray[i] = arr[i];
    delete [] currentArray; // Free memory in old array
    currentArray = arr; // Set the array to our new one
    sizeOfArray *= 2; // Double the size
  }
}

注意:以上示例未考虑空间复杂性;那说,如果你有5000个元素,除了5之外的所有元素,这个方法没有缩小它(这可能是你想要用于所有实际目的)

答案 4 :(得分:0)

建议的“矢量”是他们最安全的方式 但是,如果它只是为了让你的代码工作(没有调整大小和东西),那么下面应该有效:

#include <iostream>

using namespace std;

struct keyframe {
    bool a;
    int b;
    int c;
};


struct keyframe_file {
    const int num_views;
    const int num_keyframes;
    keyframe* keyframes;
};


int main()
{
    keyframe_file my_file = {1, 6};  // initialization needed bcause of 'const int'

    my_file.keyframes = new keyframe[my_file.num_keyframes];

    for (int i = 0; i < my_file.num_keyframes; i++)
    {
        my_file.keyframes[i].a = true;
        my_file.keyframes[i].b = 5 + i;
        my_file.keyframes[i].c = 9 - i;
    }
    return 0;
}

在代码中的某个地方,当您使用完阵列后,您必须按照前面提到的那样调用delete [] my_file.keyframes;

答案 5 :(得分:-1)

使用指针并应用于您的结构!

int *p;
p = new int;

#include <iostream>
using namespace std;

struct keyframe {
    bool a;
    int b;
    int c;
};


struct keyframe_file {
    const int num_views;
    const int num_keyframes;
    keyframe *keyframes;
};


int main() {
    keyframe_file my_file;
    my_file.num_views = 1;
    my_file.num_keyframes = 6;

    for (int i = 0; i < my_file.num_keyframes; i++){
         my_file.keyframes = new keyframe; //<---
    }

    my_file.keyframes[0].a = true;
    my_file.keyframes[0].b = 5;
    my_file.keyframes[0].c = 9;

    return 0;

}

答案 6 :(得分:-1)

在c ++中使用动态数组时有一个基本规则,特别是在结构或类中使用它时,它会删除你不再需要的东西。

如果你想让你的结构动态化,那很容易,只需用[]替换*,数组就会变得动态,但它还没有结束,还有很多工作要做。 / p>

你必须构造数组并将它摧毁,并且使用析构函数来驱逐它是可能的和有用的,如下所示:

struct keyframe_file
{
    const int num_views;
    const int num_keyframes;
    keyframe* keyframes;

    ~keyframe_file() // this is the destructor
    {
        delete[] keyframes;
    }
};

然而,即使该代码根本不起作用,因为在创建它之后将值赋值给变量my_file中的常量,它在c ++中是非法的,然后你应该使用类。

使用具有动态数组的类非常简单有趣,使您的代码非常好,您不必知道太多,只需了解什么是构造函数初始化程序析构函数私有公开,继续使用以下代码:

#include <iostream>

using namespace std;

struct keyframe
{
    bool a;
    int b,c;
};

class keyframe_file
{
public:
    keyframe_file(int NV, int NKF):num_keyframes(NKF),num_views(NV)
    {
        keyframes = new keyframe[num_keyframes];
    }
    ~keyframe_file()
    {
        delete[] keyframes;
    }
private:
    const int num_views;
    const int num_keyframes;
    keyframe* keyframes;
};

int main()
{
    keyframe_file my_file(1,6);
    return 0;
}

此代码非常有效,它允许您在创建对象(变量)num_views时为常量num_keyframesmy_file赋值。

请记住,您是一名C ++程序员,为此感到自豪,并使用类而不是结构和动态数组而不是静态数组。

希望这很有用。