Lab 3.10.2动态数据——如何获取和消除

Lab 3.10.2 Dynamic data – how to obtain it and how to get rid of it

本文关键字:获取 动态 Lab 数据 何获取      更新时间:2023-10-16

因此,出现的问题是,

看看下面的代码——它是一个在动态数据收集上运行的程序的框架。

这个想法是使用一个结构包含两个字段:第一个字段存储集合中的元素数量,第二个字段是actualcollection(动态int的分配向量)。

正如您所看到的,集合中充满了所需数量的伪随机数据。

不幸的是,该程序需要完成,因为用于向集合添加元素的最重要函数仍然是空的。

以下是我们对功能的期望:

如果集合为空,则应该分配一个单元素向量并在其中存储一个新值;

如果集合不是空的,它应该分配一个长度比当前向量大一的新向量,然后复制所有元素从旧向量到新向量,在新向量上附加一个新值,最后释放旧向量。

我不希望得到解决方案或任何东西,但如果能给我一个正确的方向,我将不胜感激。

我已经对它进行了一段时间的修改,并设法使它至少使数组变大一个,但它似乎只复制了第一个值的位置。

我的代码只是AddToCollection下的东西,by。

#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;

}

您正在实现这一点,但您没有完全实现的是(1)col.elno = sizeof(col.elements);是不变的,实际上等价于col.elno = sizeof(a_pointer);(这不是您想要的),以及(2)在AddToCollection中必须处理两个互斥条件。

  1. col.elements尚未分配,您只需分配一个1数组,并将第一个元素设置为element,同时递增col.elno;以及
  2. col.elements以前已经分配过,您必须使用newdelete[]来实现realloc (col.elements, ...)

由于您必须将旧的col.elements复制到上面第二种情况中分配的新内存块,因此包含<cstring>以提供memcpy在这方面的帮助是有帮助的。方法很简单。创建一个新的col.elno + 1元素整数数组,然后在delete[] col.elements之前将现有的col.elements中的memcpy添加到新的块中。然后在设置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;
}

示例使用/输出

$ ./bin/dyncolelements
How many elements? 10
[ 1 21 26 24 57 26 99 86 12 23 ]

内存使用/错误检查

$ 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)

始终验证所有堆块是否已释放,是否存在可能的泄漏以及是否报告错误。

仔细看看,如果你还有问题,请告诉我。