c++ - 将包含数组的结构推送到 vector 中

标签 c++ arrays vector struct

<分区>

我正在编写一个执行差异进化的程序。有一次,我正在将我的解决方案分类到解决方案文件中,并遇到了这个问题。我的存档是一个结构 vector :

std::vector<SingleSolution> archive;

typedef struct SingleSolution
{
    int *crop_area;
    int *envf;
    double nr_cost;
    int env_cost;
    int front;
    int feasible;
} SingleSolution;

当我进行排序并有一个解决方案要放入我的存档时,我正在创建一个 SingleSolution 并将其推送到存档:

SingleSolution member;
member.crop_area = (int *)calloc(crops + 1, sizeof(int));
member.envf = (int *)calloc(M + 1, sizeof(int));
member.front = 1;
member.feasible = feasible[member1];
member.nr_cost = nr_costs[member1];
member.env_cost = env_costs[member1];
for (int n = 1; n <= crops; n++) member.crop_area[n] = solution_crop[member1][n];
for (int n = 1; n <= M; n++) member.envf[n] = solution_env[member1][n];

archive.push_back(member);
//free(member.crop_area);
//free(member.envf);

我在推送到 vector 后释放了这些数组,因为我认为它复制了我推送的内容,但在打印存档时我看到了明显的垃圾值并意识到了原因。如您所见,我已将其注释掉。 所以我的问题是,那个 push_back 到底发生了什么?它插入数组开始的内存位置,然后我释放那个空间?有什么方法可以克服这个问题,还是我需要在主函数中创建空间并在调用排序函数时传递它,然后在完成时释放它?

最佳答案

当你这样做时:

archive.push_back(member);

您要求它使用复制构造函数复制 memberarchive vector 的末尾。您可以说“SingleSolution 中没有复制构造函数”,但实际上存在 - 编译器提供的复制构造函数,它生成结构成员的拷贝。这就是您的问题所在。您正在使用原始指针,默认的复制构造函数仅复制指针的(它们指向的内存地址 - 您的缓冲区)。

当您尝试自己管理这些资源时,这是导致未定义行为或内存泄漏的好方法。当您释放缓冲区但仍有指向旧内存的指针时,您意识到了这一点。

让我们尝试用 C++ 重写这段代码。

首先,您不需要那个 typedef

其次,您的缓冲区可以替换为 std::vector:

struct SingleSolution
{
    std::vector<int> crop_area;
    std::vector<int> envf;
    double nr_cost;
    int env_cost;
    int front;
    int feasible;
};

要填充你的结构,而不用担心内存分配/释放,你可以这样做:

SingleSolution member;

member.crop_area.resize(crops+1);
member.crop_area[0] = 0;
std::copy(&solution_crop[member1][1], &solution_crop[member1][crops+1], member.crop_area.begin()+1);

member.envf.resize(M+1);
member.envf[0] = 0;
std::copy(&solution_env[member1][1], &solution_env[member1][M+1], member.envf.begin()+1);

member.front = 1;
member.feasible = feasible[member1];
member.nr_cost = nr_costs[member1];
member.env_cost = env_costs[member1];

archive.push_back(member);

或者这个:

SingleSolution member;

member.crop_area.reserve(crops+1);
member.crop_area.push_back(0);
std::copy(&solution_crop[member1][1], &solution_crop[member1][crops+1], std::back_inserter(member.crop_area));
// or: std::copy_n(&solution_crop[member1][1], crops, std::back_inserter(member.crop_area));

member.envf.reserve(M+1);
member.envf.push_back(0);
std::copy(&solution_env[member1][1], &solution_env[member1][M+1], std::back_inserter(member.envf));
// or: std::copy_n(&solution_env[member1][1], M, std::back_inserter(member.envf));

member.front = 1;
member.feasible = feasible[member1];
member.nr_cost = nr_costs[member1];
member.env_cost = env_costs[member1];

archive.push_back(member);

关于c++ - 将包含数组的结构推送到 vector 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39029793/

相关文章:

c++ - C/C++运行时从何而来?

c++ - 如何简化模板模板参数中的enable_if别名

c++ - 如何正确地将命令行参数传递给 Windows 应用程序?

c++ - 使用 cap_gstreamer 错误编译 opencv 失败

c++ - 使用 map 代替 vector

arrays - 如何用另一个结构填充 <array> 结构

javascript - 如何在 JavaScript 中将 object.key 添加到现有数组?

javascript - JS Array Splice 删除数组中的元素

c++ - 如何在字符串数组中输入n行?

c++ - 如何迭代一个 vector ?