我正在编写一个程序,我在这个类中有一个类(或者在外面,希望它没关系)我有结构。在那个类中,我需要创建一个struct元素数组(我知道我可以使用vector,但是在程序中它只允许使用简单的动态数组)。
我将数组声明为T * arr[SIZE]
,其中T
是我的结构。唯一的问题是我不知道数组的确切大小,如果需要,需要增加它的大小。所以我编写了函数来调整它的大小:
if( some cond ){
T * tmpArr[newSIZE];
memcpy( tmp, db, newSIZE*sizeof(T));
delete [] arr;
arr = tmpArr;
}
但我收到MyClass::T[....]
与MyClass::T*[SIZE]
不兼容的错误,该错误会响应我的arr = tmpArr
表达式。
T * arr[size]
或T * arr = new T[size]
以及如何在这种情况下调整大小(并从旧的数组中释放内存)数组?
更新:
感谢您的回答,我在我的计划中做了相应的事情:
T * tmp = new T[newSIZE];
memcpy( tmp, db, newSIZE*sizeof(T) );
delete [] db;
db = tmp;
现在我得到奇怪的东西,在删除db并将db
分配给tmp
之后我尝试打印db(或tmp)中包含的所有数据,这是我得到的奇怪的事情:
Smith2 Michigan ave▒ ACME, Ltd. One ACME roa▒
Smit▒ Michigan ave` ACME, Ltd. One ACME roa "
One ACME road#@"▒▒▒▒Michigan ave`▒▒▒▒Smit▒"
▒▒ ▒8 Ltd.#Michigan avenuemith4▒aF▒
如果我在删除和分配之前打印相同的数据,我会得到我想要的普通文本。在程序之后(因为我以前没有,也许我的代码有问题,我得到Segmentation故障)。顺便说一句,我在我的窗口中使用struct
std::string
和cygwin。你知道这里有什么问题吗?
答案 0 :(得分:4)
T* tmpArr[newSIZE];
向T
声明一个可变长度指针数组。请注意,可变长度数组不是标准C ++的一部分(它们是C99的一部分,但在C ++中仅作为GCC的扩展...因此,此代码无法通过不同的编译器进行编译)。
完全合理的解决方案是使用std::vector
,但由于你自己写道,你不能使用它,所以这就是你能做的。
T* tmpArr[newSIZE];
更改为T* arr = new T[size];
T* newArr = new T[newSize]
memcpy(newArr, arr, size * sizeof(T))
delete[]
:[{1}} delete[] arr
不会更改指针本身,因此在步骤3之后您有无效的(悬空)指针,因此将指向新数组的第一个元素的指针指定给旧数组: delete
请注意arr = newArr
分配足够大的内存来保存T* arr = new T[size]
类型的size
对象,并使用T
的默认构造函数构造这些对象。然后将第一个元素的地址分配给T
,使其指向连续的内存块,这些元素位于此处。
答案 1 :(得分:3)
T arr[N];
此表单的声明为您提供了一个具有自动存储持续时间的大小为N
的数组。这是固定的。您无法更改此数组的大小。大小N
必须是编译时常量。
T* arr = new T[N];
此声明定义了具有自动存储持续时间的T*
。但是,它还会创建一个大小为N
且动态存储持续时间的数组。这里,大小N
不需要是编译时常量。
然而,这对你没有帮助。您仍然无法调整动态数组。您必须执行delete[] arr
来销毁旧数组,然后执行new T[NewSize]
并以某种方式复制数据。
这肯定会变得混乱,事实上它已经变得混乱了。在您的代码中,您混合了两种不同类型的分配。即使delete[] arr
没有动态存储持续时间,您也尝试arr
。你根本做不到这一点。您也无法将一个数组分配给另一个数组,如arr = tmpArr;
。
相反,C ++标准库提供了许多称为容器的类型。这使得动态可调整大小的元素序列变得非常容易。例如,使用std::vector<T>
会更好。
std::vector<T> arr;
std::vector
以没有元素开头。您只需执行arr.push_back(value)
即可添加元素。您还可以通过arr.resize(newSize)
轻松地一次调整矢量大小。
答案 2 :(得分:1)
我猜你试图删除你创建的数组:
T array[size];
但是你不应该在这上面调用delete。当该数组超出范围时,将删除该数组。
如果要创建数组并在之后释放它,则在声明数组时必须使用new
运算符。如果您想要释放它,请使用delete
。
但无论如何,你可能想要使用std::vector
而不是自己尝试。如果你有兴趣了解这些东西,有一个关于来自微软的频道9的视频系列由Stephen T. Lavavej在这里:
答案 3 :(得分:0)
简单的解决方案不是重新发明方形轮,而是使用标准库中已经圆润的std::vector<Type>
模板。
答案 4 :(得分:0)
我认为你实际上想要存储指向T
的指针。你需要:
*
,因为您要分配一个指针数组T
,tmpArr
和arr
所以:
// arr definition
T **arr;;
// arr resizing code
if( some cond ){
T **tmpArr;
memcpy( tmp, db, newSIZE*sizeof(T *));
delete [] arr;
arr = tmpArr;
}
您的数组存储指向T
的指针,而不是T
,并且在编译时不知道tmpArr
大小,因此您无法在其中指定它类型。
警告:如果新大小小于当前大小,则会丢失数组末尾的指针。您应该在其上添加一个测试,并删除这些额外的T
(如果您的容器拥有它们),或者只是抛出异常,因为代码只会增加数组的大小。