将值从一个向量复制到另一个向量(从book)

Copying values from one vector to another (from book)

本文关键字:向量 另一个 book 复制 一个      更新时间:2023-10-16

考虑这段代码。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector <int *> test;
    vector <int *> v;
    int *a = new int;
    int *b = new int;
    *a = 1;
    *b = 2;
    v.push_back (a);
    v.push_back (b);
    for (int i = 0; i < 2; ++i)
    {
        int n = *v[i];
        test.push_back (&n);
    }
    cout << *test[0] << " " << *test[1] << endl;
    delete a;
    delete b;
    return 0;
}

问题的语句是:

"给定这段代码,回答以下问题:

  1. 为什么"测试"向量只包含2 ?

  2. 我们如何改变for循环正确复制(只有代码内for循环)?"

这些问题我都答不上来,如果你能帮点忙,我将不胜感激。

这段代码引入了悬空指针。循环体看起来像这样:

{
    int n = *v[i];
    test.push_back (&n);
}

局部变量n在循环体结束时失去作用域,因此指针&n现在是一个悬垂指针。如果碰巧test只包含2,这只是随机产生的未定义行为

如果您想"正确"地将数据复制到test,您可以将for循环体更改为:

{
    int* n = new int;
    *n = *v[i];
    test.push_back (n);
}

将两个指向n的相同指针压入test数组。n等于第一个数组的最后一个元素。注意,控制流退出循环后,所有指向n的指针都无效。所以,实际上你的test数组包含无效指针,而不是指向2s的指针。

您应该创建每个整数的副本:

int* n = new int(*v[i]);
test.push_back (n);

还要注意这里存在内存泄漏。使用new创建的每个int稍后应该使用delete销毁。

第一个问题是一个技巧问题:vector包含指向一个不再存在的变量的指针,并且解引用可能导致几乎任何输出。我想在一些机器和编译器上,它会打印所有的2 s。

我不明白这个练习要做什么(例如为什么要使用指针的向量),所以我不能真正帮助如何解决这个问题。

一种方法是让test按值存储:

首先将测试向量更改为vector <int> test;

然后将push_back更改为test.push_back (n);之类的内容,最后将print语句删除现在不需要的*操作符。

编辑注释:

首先,我怀疑这本书:它不应该展示未定义的行为或指向单个内置类型的原始指针。但是如果你愿意,你可以改变你的循环体:

 for (int i = 0; i < 2; ++i)
 {
     int* n = new int;
    *n = *v[i];
     test.push_back (&n);
 }

请注意,这两种方法都会导致内存泄漏,除非您稍后将这些指针delete,按值存储可以消除这个问题。

我认为这个问题的前提是错误的。循环将两个元素添加到test中,每个元素都包含自动变量n的地址,其作用域限制在循环体中。不能保证n在两次循环中都被分配到相同的内存位置,但我认为大多数编译器可能会在两次循环中重用相同的位置。

此外,n在输出语句的作用域之外。因此,引用test中的指针到这些内存位置是未定义的。同样,它们很有可能仍然包含在循环中分配的值。

因此,只有在第二次循环中为n重用相同的位置,并且在执行输出语句时该位置没有被覆盖,输出才会是"22 2"。

2)为了得到输出"1 2"而不改变循环外的任何东西,可以将n的定义更改为int& n = *v[i],这将是给定代码的单个字符更改,尽管最终结果相当奇怪。

一个更简单的解决方案是取消临时的n,直接使用test.push_back(v[i])