C++ 实验3.10.2动态数据&x2013;如何获得它,如何摆脱它
所以现在的问题是, 请看下面的代码——它是一个在动态数据收集上运行的程序的框架 这个想法是使用一个结构 包含两个字段:第一个字段存储集合中的元素数,第二个字段是actualcollection(动态 分配的整数向量) 如您所见,集合中填充了所需数量的伪随机数据 不幸的是,程序需要完成,因为用于向集合添加元素的最重要的函数仍然是空的 以下是我们对函数的期望: 如果集合为空,则应分配一个单元素向量并在其中存储一个新值 如果集合不是空的,它应该分配一个长度比当前向量大1的新向量,然后复制所有 从旧向量到新向量的元素,将新值附加到新向量,最后释放旧向量 我不希望有什么解决办法,除非有一个指向正确方向的指针,否则我将不胜感激 我已经对它进行了一段时间的修补,并设法使它至少使数组变大一倍,但它似乎只复制了第一个值的位置 我的代码就是AddToCollection下的内容,顺便提一下C++ 实验3.10.2动态数据&x2013;如何获得它,如何摆脱它,c++,C++,所以现在的问题是, 请看下面的代码——它是一个在动态数据收集上运行的程序的框架 这个想法是使用一个结构 包含两个字段:第一个字段存储集合中的元素数,第二个字段是actualcollection(动态 分配的整数向量) 如您所见,集合中填充了所需数量的伪随机数据 不幸的是,程序需要完成,因为用于向集合添加元素的最重要的函数仍然是空的 以下是我们对函数的期望: 如果集合为空,则应分配一个单元素向量并在其中存储一个新值 如果集合不是空的,它应该分配一个长度比当前向量大1的新向量,然后复制所有 从旧向量
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
struct Collection {
int elno;
int *elements;
};
void AddToCollection(Collection &col, int element) {
// Insert your code here
if(col.elements != NULL) {
col.elno = sizeof(col.elements);
++col.elno;
int *jeffry = new int[col.elno + 1];
jeffry[col.elno] = element;
for (int f = 0; f < (col.elno - 1); f++) {
jeffry[f] = col.elements[f];
}
col.elements = jeffry;
}
if(col.elements == NULL){
col.elements =new int[element];
}
}
void PrintCollection(Collection col) {
cout << "[ ";
for(int i = 0; i < col.elno; i++)
cout << col.elements[i] << " ";
cout << "]" << endl;
}
int main(void) {
Collection collection = { 0, NULL };
int elems;
cout << "How many elements? ";
cin >> elems;
srand(time(NULL));
for(int i = 0; i < elems; i++)
AddToCollection(collection, rand() % 100 + 1);
PrintCollection(collection);
delete[] collection.elements;
return 0;
#包括
#包括
#包括
使用名称空间std;
结构集合{
国际电信组织;
int*元素;
};
void AddToCollection(Collection&col,int元素){
//在这里插入您的代码
if(列元素!=NULL){
col.elno=尺寸of(col.elements);
++埃尔诺上校;
int*jeffry=新int[col.elno+1];
杰弗里[col.elno]=元素;
对于(int f=0;f<(col.elno-1);f++){
杰弗里[f]=列元素[f];
}
col.elements=杰弗里;
}
if(col.elements==NULL){
col.elements=新整数[元素];
}
}
作废打印集合(集合列){
虽然你已经达到了目标,但你还没有完全达到目标:(1)col.elno=sizeof(col.elements);
是不变的,实际上相当于col.elno=sizeof(a_指针);
(这不是你想要的),以及(2)必须在AddToCollection
中处理两个相互排斥的条件
col.elements
尚未分配,您只需分配一个1
数组,并在递增col.elno
的同时将第一个元素设置为element
;以及
col.elements
以前已分配,您必须使用new
和delete[]
基本上realloc(col.elements,…)
由于您必须将旧的col.elements
复制到您在上述第二种情况下分配的新内存块中,因此包含
有助于提供memcpy
在这方面的帮助。方法很简单。创建一个包含col.elno+1
元素的新整数数组,然后创建memcpy
您现有的col。在删除[]列元素之前,将元素
分配到新块中。然后在设置col.elements[col.elno++]=element;
之前,只需将新内存块分配给col.elements
你可以做:
void AddToCollection (Collection &col, int element)
{
if (!col.elements)
col.elements = new int[1];
else {
int *tmp = new int[col.elno + 1];
memcpy (tmp, col.elements, col.elno * sizeof *col.elements);
delete[] col.elements;
col.elements = tmp;
}
col.elements[col.elno++] = element;
}
注意:您应该始终使用内存错误检查程序来验证内存使用情况,例如针对Linux的valgrind
。(每个操作系统都有类似的检查程序)
然后,您的程序变成:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
struct Collection {
int elno;
int *elements;
};
void AddToCollection (Collection &col, int element)
{
if (!col.elements)
col.elements = new int[1];
else {
int *tmp = new int[col.elno + 1];
memcpy (tmp, col.elements, col.elno * sizeof *col.elements);
delete[] col.elements;
col.elements = tmp;
}
col.elements[col.elno++] = element;
}
void PrintCollection(Collection col) {
cout << "[ ";
for(int i = 0; i < col.elno; i++)
cout << col.elements[i] << " ";
cout << "]" << endl;
}
int main(void) {
Collection collection = { 0, NULL };
int elems;
cout << "How many elements? ";
cin >> elems;
srand (time(NULL));
for (int i = 0; i < elems; i++)
AddToCollection (collection, rand() % 100 + 1);
PrintCollection(collection);
delete[] collection.elements;
return 0;
}
内存使用/错误检查
$ valgrind ./bin/dyncolelements
==11375== Memcheck, a memory error detector
==11375== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==11375== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==11375== Command: ./bin/dyncolelements
==11375==
How many elements? 10
[ 14 32 40 65 10 4 38 72 64 83 ]
==11375==
==11375== HEAP SUMMARY:
==11375== in use at exit: 0 bytes in 0 blocks
==11375== total heap usage: 11 allocs, 11 frees, 72,924 bytes allocated
==11375==
==11375== All heap blocks were freed -- no leaks are possible
==11375==
==11375== For counts of detected and suppressed errors, rerun with: -v
==11375== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
始终验证是否释放了所有堆块,是否存在可能的泄漏,是否没有报告错误
请仔细查看,如果您有进一步的问题,请告诉我。当说明中说要使用向量时,您为什么要使用手动内存管理?看到标题并期望任务转储。很高兴看到代码。我将在一秒钟内检查代码,但标题不是很有描述性。它几乎没有说明您遇到的问题s、 问题itslef很少说明问题所在。这意味着我可能会深入研究您的代码,找到您不需要的东西。我建议在提问时要明确。讨论col.elements=new int[element]
with。向它解释此行的作用以及您希望它做什么。无关:而不是delete[]C++中的元素, >代码>主< /代码>,将析构函数添加到<代码>集合>代码>中进行清理。这是析构函数的作用。但是,一旦你这样做,你就必须担心。现在你可以避免它,但是现在你也可以学习它,因为你不能编写好的,不平凡的C++代码,而没有很好的处理。e规则三。好的。现在我已经加载了更新的问题,它不再那么无关了。这里有另一个链接:。一般来说,一个对象应该管理它的所有资源。做得好,对象就会隐藏它所有的内部复杂性。使用构造函数和析构函数,并将大部分函数移到集合中。非常感谢。是的,我可能会发现我得到了一些东西的地址,但是不知道什么是错的。C.C.元素是非常整洁的,我不认为这个操作符和我应该的一样多。非常感激。很高兴有帮助。这是一个很好的练习来理解使用<代码>新/删除> /代码>和<代码> MalC/CalLog/R。EOLC/正如你将在很多旧的代码库中看到的。但是,C++的容器,如<代码>向量、字符串、映射等。 提供自动内存处理,而应该使用(更容易出错)。
$ valgrind ./bin/dyncolelements
==11375== Memcheck, a memory error detector
==11375== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==11375== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==11375== Command: ./bin/dyncolelements
==11375==
How many elements? 10
[ 14 32 40 65 10 4 38 72 64 83 ]
==11375==
==11375== HEAP SUMMARY:
==11375== in use at exit: 0 bytes in 0 blocks
==11375== total heap usage: 11 allocs, 11 frees, 72,924 bytes allocated
==11375==
==11375== All heap blocks were freed -- no leaks are possible
==11375==
==11375== For counts of detected and suppressed errors, rerun with: -v
==11375== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)