问题描述
||
我想创建一个结构并将其在另一个结构中用作数组。我的问题是我不知道要分配多大的数组,只有在使用函数时我才知道。我的意思是我想使用[]而不是诸如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;
}
解决方法
如果适合您的目的,那么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个元素之外的所有元素,则不缩小该方法(这可能是您出于所有实际目的所希望做的)
, 用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(...);
}
, 您的代码看起来几乎是正确的,除了两件事:
keyframes
必须是keyframe*
,而不是keyframe[]
您忘了“ 10”分配的内存
, 那是不完整的类型。在C ++中,必须为数组提供大小,并且在编译时必须知道大小。
您使用的是new
,应该使用它使用指针。
struct keyframe_file {
const int num_views;
const int num_keyframes;
keyframe *keyframes;
};
但是,正如@DeadMG已经建议的那样,std::vector<keyframe>
仍然是一个更好的选择。
顺便说一下,结构中的前两个成员是const
,这意味着它们不能像在代码中那样被赋值。必须使用您希望它们保存的值初始化它们。这意味着,现在使用ѭ15,您必须包含一个构造函数以初始化该结构,因为该结构不再是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!
, 建议的“向量”是它们最安全的方法。
但是,如果仅是使代码正常工作(不调整大小和填充内容),则以下内容应该有效:
#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;
。
, 在c ++中使用动态数组时,有一个基本规则,尤其是在结构或类中使用它时,它就是删除不再需要的内容。
如果要使结构动态化,这很容易,只需将ѭ19替换为*
,数组就可以动态化,但是还没有结束,有很多工作要做。
您必须构造数组并将其销毁,然后使用析构函数销毁它是可能且有用的,如下所示:
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;
}
该代码效果很好,它允许您在创建对象(变量)my_file
时一次将值赋给常量num_views
和num_keyframes
。
请记住,您是C ++程序员,为此感到自豪,并使用类而不是结构和动态数组而不是静态数组。
希望这很有用。
, 使用指针并应用于您的结构!
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;
}