实验室3.10.2动态数据–如何获取数据以及如何摆脱数据

时间:2019-02-11 06:50:53

标签: c++

所以,出现的问题是

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

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

如您所见,集合中填充了所需数量的伪随机数据。

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

这是我们对函数的期望:

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

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

我不希望找到解决方案或其他任何东西,但是朝正确方向的指针将不胜感激。

我已经花了一段时间,设法使它至少使数组大一个,但似乎只复制了第一个值的位置。

我的代码只是by的AddToCollection下的内容。

#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 个答案:

答案 0 :(得分:2)

您正在到达那里,但是您所得到的不是(1)col.elno = sizeof(col.elements);是不变的,实际上等效于col.elno = sizeof(a_pointer);(这不是您想要的),以及(2)在那里您必须在AddToCollection中处理两个互斥的条件。

  1. col.elements尚未分配,您只需分配1的数组,并在递增element的同时将第一个元素设置为col.elno即可;和
  2. col.elements之前已经分配过,基本上,您必须使用realloc (col.elements, ...)new delete[]

由于您必须将旧的col.elements复制到在上述第二种情况下分配的新内存块中,因此包含<cstring>可以提供memcpy来帮助您解决此问题。该方法很简单。创建一个由col.elno + 1元素组成的新整数数组,然后将现有memcpy col.elements移至新块delete[] col.elements之前。然后只需在设置col.elements之前将新的内存块分配给col.elements[col.elno++] = element;

您可以这样做:

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)

始终验证是否释放了所有堆块,并且没有泄漏的可能,也没有错误报告。

仔细检查一下,如果还有其他问题,请告诉我。