[英]beginner question about arrays in structs in C++
我想创建一个结构并将其在另一个结构中用作数组。 我的问题是我不知道要分配多大的数组,只有在使用函数时我才知道。 我的意思是我想使用[]而不是诸如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;
}
使用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[]
delete
分配的内存 那是不完整的类型。 在C ++中,必须为数组提供大小,并且在编译时必须知道大小。
您正在使用new
,与你应该使用指针 。
struct keyframe_file {
const int num_views;
const int num_keyframes;
keyframe *keyframes;
};
但是,正如@DeadMG已经建议的那样, std::vector<keyframe>
仍然是一个更好的选择。
顺便说一句,前两个成员在结构体中是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!
如果适合您的目的,那么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个元素之外的所有元素,则此方法将不缩小它(这可能是您出于所有实际目的所要做的)
建议的“向量”是它们最安全的方法。
但是,如果仅是使您的代码正常工作(不调整大小和填充内容),则应该可以进行以下操作:
#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;
如前所述。
使用指针并应用于您的结构!
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;
}
在c ++中使用动态数组时有一个基本规则,尤其是在结构或类中使用它时,它就是删除不再需要的内容。
如果你想使你的结构动态的,这很容易,只需更换[]
与*
和阵列将成为动态的,但还没有结束,还有大量的工作。
您必须构造数组并将其销毁,然后使用析构函数销毁它是可能且有用的,如下所示:
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 ++程序员,为此感到自豪,并使用类而不是结构和动态数组而不是静态数组。
希望这很有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.