我认为这是一个微不足道的问题,但是我找不到特定的解决方案。我正在尝试使用push_back()
函数将数组附加到向量中。这是代码:
int main()
{
std::vector<int*> matchVector;
int msmTemp[3];
msmTemp[0] = 1;
msmTemp[1] = 2;
msmTemp[2] = 3;
matchVector.push_back(msmTemp);
msmTemp[0] = 4;
msmTemp[1] = 7;
msmTemp[2] = 0;
matchVector.push_back(msmTemp);
for(auto i : matchVector)
{
for(int j = 0; j<3; j++)
{
cout<<i[j]<<", ";
}
cout<<"\n";
}
return 0;
}
我得到的输出是4,7,0的两倍。我不明白为什么我看不到先前的值1,2,3?是否因为上面定义的向量matchVector
的类型?我认为它只需要数组即可。
答案 0 :(得分:4)
int*
是一个指向整数的指针。
int[3]
是3个整数的数组。
由3个整数组成的数组在放下指向第一个元素的指针时“衰减”。
执行push_back(msmTemp)
时,将指向msmTemp
的第一个元素的指针推入vector
。
C ++中的指针不拥有其指向的内容。两个push_backs之后的向量包含两个指针,两个指针均指向同一数组msmTemp
。
稍后在向量上进行迭代时,您将依次获得两个指针。每个都指向msmTemp
。
然后使用[]
为这些指针建立索引。当拥有指向数组第一个元素的指针时,可以使用[]
来访问数组的其他元素。 [0]
是第一个元素,[1]
是第二个元素,等等。
因此,您查看msmTemp
中的3个元素(幸运的是,它包含3个元素)并对其进行两次查看,因为向量中有两个指针。
您可以注入以下元素:
std::vector<int> matchVector;
int msmTemp[3];
msmTemp[0]={1};
msmTemp[1]={2};
msmTemp[2]={3};
matchVector.insert( matchVector.end(), std::begin(msmTemp), std::end(msmTemp) );
等最终得到一个包含6个元素而不是两个数组的向量。
如果要将数组作为值,则需要std::array
:
std::vector< std::array<int,3> > matchVector;
std::array<int, 3> msmTemp;
,然后您的代码按编写的方式工作。 std::array
是一种库类型,其行为类似于原始数组,但不存在原始数组的指针衰减问题。
答案 1 :(得分:2)
忘记int[3]
命名类型。 C数组的行为不像明智的值。数组名为std::array<type, count>
。
#include <vector>
#include <array>
int main()
{
std::vector<std::array<int, 3>> matchVector;
std::array<int, 3> msmTemp;
msmTemp[0] = 1;
msmTemp[1] = 2;
msmTemp[2] = 3;
matchVector.push_back(msmTemp);
msmTemp[0] = 4;
msmTemp[1] = 7;
msmTemp[2] = 0;
matchVector.push_back(msmTemp);
for(auto & arr : matchVector)
{
for(auto i : arr)
{
std::cout << i <<", ";
}
std::cout<<"\n";
}
return 0;
}
答案 2 :(得分:1)
其他答案已经说明了如何修复您的代码。我认为解释为什么您的代码的行为方式也很好:
在这里,您告诉编译器创建一个{<1>},该指针将指针保留为int:
std::vector
在这里,您告诉编译器在堆栈上分配适合3个整数的空间:
std::vector<int*> matchVector;
在这里,您告诉编译器将值int msmTemp[3];
,1
和2
写入先前分配的内存中:
3
在这里,您告诉编译器获取分配的空间的地址,将其视为指针,然后将其传递给msmTemp[0] = 1;
msmTemp[1] = 2;
msmTemp[2] = 3;
。这称为array decaying:
push_back
您的matchVector.push_back(msmTemp);
现在包含 1 元素,这是指向您的堆栈上分配为容纳3个整数的内存地址的指针。
在这里,您告诉编译器在先前分配的内存中写入值matchVector
,4
和7
。请注意,这仍然是与以前相同的内存块:
0
在这里,您告诉编译器再次获取分配空间的地址,将其视为指针,然后将其传递给msmTemp[0] = 4;
msmTemp[1] = 7;
msmTemp[2] = 0;
:
push_back
因此matchVector.push_back(msmTemp);
现在包含 2个相同的值,每个值均指向相同的内存位置。具体来说,您上次将matchVector
,4
和7
写入的内存位置。