关于内存地址的问题
Questions regarding memory addresses
基于以下代码,我有几个问题:
- 为什么
&s->m1
和&s->m2
之间的差异是4字节,而double
的大小是8 - 为什么调整
m3
的大小不会更改地址?我预计&s->m4
在调整m3
的大小后会进一步偏移 - 为什么即使我删除了
m1
,所有地址都保持不变
main.cpp:
#include <iostream>
#include <vector>
struct S
{
int m0;
int m1;
double m2;
std::vector<int> m3;
std::vector<int> m4;
};
int main()
{
S* s = new S();
s->m3.resize(7);
std::cout << &s->m0 << std::endl;
std::cout << &s->m1 << std::endl;
std::cout << &s->m2 << std::endl;
std::cout << &s->m3 << std::endl;
std::cout << &s->m4 << std::endl;
return 0;
}
输出:
0x1860c20
0x1860c24
0x1860c28
0x1860c30
0x1860c48
-
sizeof(s->m2(是8个字节这一事实影响了&s->m2和&s->m3,而不是&s->m1和&s->m2.
-
调整m3的大小不会更改地址,因为std::vector使用动态堆内存来存储向量的内容。
-
如果删除m1,因为下一个结构元素m3位于8字节的边界上,编译器会添加4字节的填充以保持对齐。
哦。
首先,在访问说明符之间(我相信在C++11中以及以后的版本中,对于所有具有相同访问权限的项(,结构中的项被放置在严格增加的内存地址处,就程序本身所知。
然后,根据你的申报
struct S
{
int m0;
int m1;
double m2;
std::vector<int> m3;
std::vector<int> m4;
};
…你问
">1。为什么
&s->m1
和&s->m2
之间的差异是4字节,而double
的大小是8?
对象的地址是该对象的起始地址,它的第一个字节的地址,即该对象中的最低地址。
所以m1
的地址就是m1
的起始地址。如果类型为int
的m1
是4个字节,则下一项m2
开始时至少高出4个字节。你的编译器也是如此。然而,编译器可以自由插入填充,因此m2
可以放得更高。对于其他编译器,int
可以是8个字节,甚至只有1个字节(它必须至少是16位,因此后一种可能性意味着char
,即C++存储单元,至少是16个位,就像在一些德州仪器的数字信号处理器上一样(。
">2。为什么调整
m3
的大小不会更改地址?我预计CCD_ 20在调整CCD_ 21的大小后会进一步偏移。
C++中的所有对象都是固定大小的,由sizeof
运算符给定。但它们可以保存指向内存块的指针,而内存块的大小可能会发生变化。m3
是std::vector
,它使用这种技术:它保存一个指向某个内部缓冲区的指针。您可以通过.capacity()
方法检查该缓冲区的大小。您可以通过.size()
方法检查当前使用了多少。
">3。为什么即使我删除了
m1
,所有地址都保持不变?
如果观察结果正确,则可能是double
类型的m2
,以及编译器和编译选项,具有8个字节的对齐。也就是说,double
必须放置在8的倍数的地址上。由于在m2
之前仍然有int
类型的m0
,并且对于编译器,int
是4个字节,因此编译器插入4个字节的填充。
编译器不能为了更好的空间利用率而移动这些项,因为C++标准要求它将它们按递增的地址顺序放置,因为没有介入的访问说明符。
然而,大多数编译器支持各种#pragma
来影响它们的填充和对齐决策。
- 从 C++ 中的函数返回数组地址问题
- 初学者问题:C++指针/地址 - 和变量之后不是以前?
- 如何解决地址问题
- 如何调试错误代码 77:cudaErrorIllegal地址当 cuda-memcheck 没有发现问题时
- 迷宫构造函数问题 [线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)]
- LPVOID 问题不接受内存地址
- 通过引用地址传递问题
- 交换地址的问题
- 将文件的常量字符* 地址传递给 ifstream 对象的问题
- 线程1:EXC_BAD_ACCESS(代码=1,地址=0x0)问题生成
- 关于取消引用和地址空间的基本C++指针问题
- 比较套接字地址的问题
- 通过池分配器中的内存地址访问可用列表节点时出现问题
- 提升 unix 上的 UDP 套接字问题 - 绑定:地址已在使用中
- libC++库的地址净化构建为什么会在libcxx类中出现不可复制的ASAN问题
- 关于内存地址的问题
- 修复了TinyWireS库的i2c地址问题
- 关于c++中地址空间的问题
- C++ 不接受对象字符串中的@符号吗?似乎是地址问题?
- 将三维指针的第一个地址转换成一维指针时出现问题