c++ - 矢量打印地址的元素显示垃圾
问题描述
考虑:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
vector<char> vChar;
vChar.push_back('a');
vChar.push_back('b');
vChar.push_back('c');
vChar.push_back('d');
vector<int> vInt;
vInt.push_back(1);
vInt.push_back(2);
vInt.push_back(3);
vInt.push_back(4);
cout << "For char vector Size:" << vChar.size() << " Capacity:" << vChar.capacity() << "\n";
for(int i=0; i < vChar.size(); i++)
{
cout << "Data: " << vChar[i] << " Address:" << &vChar[i] << "\n";
}
cout << "\nFor int vector Size:" << vInt.size() << " Capacity:" << vInt.capacity() << "\n";
for (int i = 0; i < vInt.size(); i++)
{
cout << "Data: " << vInt[i] << " Address:" << &vInt[i] << "\n";
}
return 0;
}
上面代码的示例输出是:
For char vector Size:4 Capacity:4
Data: a Address:abcd²²²²αPⁿ▀┬
Data: b Address:bcd²²²²αPⁿ▀┬
Data: c Address:cd²²²²αPⁿ▀┬
Data: d Address:d²²²²αPⁿ▀┬
For int vector Size:4 Capacity:4
Data: 1 Address:000001F020F80420
Data: 2 Address:000001F020F80424
Data: 3 Address:000001F020F80428
Data: 4 Address:000001F020F8042C
对于每个原始数据类型,内存位置都是连续的,除了 char。它在屏幕上打印一些垃圾值。
我尝试添加 v.reserve(4),但输出是相同的。
解决方案
对于每个原始数据类型,内存位置都是连续的,除了
char
. 它在屏幕上打印一些垃圾值。
对于这两种情况,“内存位置”以完全相同的方式连续。唯一的区别在于您显示结果的方式。当你这样做时:
cout << "Data: " << vChar[i] << " Address:" << &vChar[i] << "\n";
当您在 1 中的单个1上应用( address-of ) 时,您给出std::operator<<(std::basic_ostream)
了 a ,这使其将其视为 C 样式字符串 - 意思是,它寻找终止的 null。在你的情况下,这个null确实是在一些垃圾之后。2但是你肯定有一些垃圾之后就好了,只是你没有打印它。3char*
&
char
vector
vector<int>
如果您想获得与 相同的打印输出vector<int>
,则可以显式转换为void
指针,因此std::cout
将其视为要打印的地址(此处为重载 (7)),而不是字符串:
cout << "Data: " << vChar[i] << " Address:" << static_cast<void*>(&vChar[i]) << "\n";
在这种情况下,输出为:
For char vector Size:4 Capacity:4
Data: a Address:0x1c39810
Data: b Address:0x1c39811
Data: c Address:0x1c39812
Data: d Address:0x1c39813
For int vector Size:4 Capacity:4
Data: 1 Address:0x1c39960
Data: 2 Address:0x1c39964
Data: 3 Address:0x1c39968
Data: 4 Address:0x1c3996c
1 char&
准确地说,std::vector<T>::operator[]
返回 a T&
。
2请注意,查找不是由您放置在那里的终止 null构成未定义的行为,因为它可能使您访问不打算为此目的访问的内存。
3如果您执行反向转换以std::cout
将vector<int>
元素视为 C 样式字符串,您可以尝试自己查看:
cout << "Data: " << vInt[i] << " Address:" << reinterpret_cast<char*>(&vInt[i]) << "\n";
同样,请记住这意味着未定义的行为,因为打印代码将在内存中查找终止的 null,而您肯定没有它可以找到。
推荐阅读
- amazon-s3 - 我们如何强制融合 kafka 连接 s3 sink 冲洗
- php - 仅半满时 Composer 磁盘满错误
- php - 如何在没有电子邮件验证的情况下注册?
- angular - 如何禁用仪表板上的某些导航项目取决于 angular 5 的角色?
- c++ - 在定义类成员函数时是否允许使用传递参数类对象的成员变量?
- php - golang 和 node/php 之间的 AES-256-CBC 加密不匹配
- ethereum - Solidity tx.destination.call.value(tx.value)(tx.data)
- mockito - 在单元测试中传递给控制器时,FakeRequest 似乎为 Null
- javascript - D3 v4 饼图默认文本
- synchronization - Angular 5 和 Ionic 3 中的数据同步问题