这可以在 C 中得到保证,因为 WG14/N1570 中有以下句子:
6.2.5/20 ... 数组类型描述了具有特定成员对象类型的连续分配的非空对象集,称为元素类型。
但是在WG21/N4527中,即在C++中,对应的句子变成了
8.3.4/1 ...数组类型的对象包含连续分配的 N 个 T 类型子对象的非空集合。
而“描述”一词改为“包含”,这不能保证数组的地址等于它的第一个元素的地址。这种改变是有意的还是无意的?如果是故意的,数组的地址是否等于它在 C++ 中的第一个元素的地址?如果是这样,C++ 标准中的哪一段可以保证这一点?
我想在 64 位 ARM 上的 32 位地址空间内分配一个缓冲区。换句话说,我想确保我的缓冲区绑定到较低的 32 位地址空间。你知道有一个很好的 C 函数可以做到这一点吗?
我有一个变量,其地址作为第四个参数传递给setsocketopt。请注意,此参数被声明为常量指针 ( const void *optval)。
在我提交供审查的补丁中,我将该变量的声明更改为 static constexpr。此更改的审阅者对此表示担忧:他认为是否始终可以获取 constexpr 的地址是值得怀疑的。他建议我将其设为常量。在谷歌搜索后,我找不到太多关于 constexpr 变量地址的信息以及对此的担忧。有人可以解释一下与 constexpr 变量的地址有关的保证以及使用它的注意事项(如果有)吗?
如果它有帮助,这里是代码(我添加的static constexpr,这只是int之前的代码):
static constexpr int ONE = 1;
setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &ONE, sizeof(ONE));
Run Code Online (Sandbox Code Playgroud)
谢谢!
int (*p)[4] , *ptr;
int a[4] = {10,20,30,40};
printf("%p\n%p\n%p",&a,a,&a[0]);
p = &a ;
//p=a; gives error
//ptr = &a; gives error
ptr = a;
Run Code Online (Sandbox Code Playgroud)
输出:
0x7ffd69f14710
0x7ffd69f14710
0x7ffd69f14710
Run Code Online (Sandbox Code Playgroud)
我试图了解 what a、&a和&a[0]返回及其起始变量的内存地址。那么,为什么我会在其中一些作业中出错?
我的意思是,如果p = &a = 0x7ff...有效,为什么不p = a = 0x7ff..呢?
如果可能的话,任何人都可以通过框图让我理解这个 p 和 ptr 实际指向的位置。或者他们只是指向相同。但它们是不同的东西,我肯定知道。
只是我的问题的一个简单示例:
while(condition){
int number = 0;
printf("%p", &number);
}
Run Code Online (Sandbox Code Playgroud)
该变量将始终位于相同的内存地址中。为什么?
那么在循环内部或外部声明它之间的真正区别是什么?
我是否需要malloc每次迭代都使用变量来获得不同的地址?
我正在尝试阅读英特尔软件开发人员手册以了解操作系统的工作原理,这四个寻址术语让我感到困惑。以上是我的理解,如有不对请指正。
线性地址:对于一个孤立的程序来说,似乎是一长串内存,从地址 0 开始。该程序的所有段都将从其线性地址开始寻址。它可能在内存或磁盘中。
物理地址:出现在 ram 或主存储器引脚中的地址。
逻辑地址:磁盘和内存中交换内存的组合。所有程序的所有线性内存都将保留在逻辑地址空间中。它只能由内核模式使用。从逻辑地址到物理地址的转换是由内部硬件完成的。
虚拟地址:虚拟地址与线性地址相同。它只会被操作系统中的用户模式使用。操作系统将从逻辑地址映射虚拟地址。
那太疯狂了!
为了弄清楚对象在C++中是如何存储在内存中的,
我写了下面的代码来查看变量的地址。
但事情变得更加混乱。
所以在下面我想知道
为什么 1 不同于 2 ------这是否意味着它是一个指针?但为什么?
为什么 1 与 3 不同 ------它是通过引用传递的,它们应该是相同的?!
#include <iostream>
#include <vector>
using namespace std;
class A {
public:
A(int age, string name) : age_(age), name_(name){};
void SetAge(int age) {
age_ = age;
}
int age_;
string name_;
};
void insert(vector<A>& p) {//passed by reference
A a1{1, "tom"};
printf(" p: %p\n", p); // p: 0x7ffc6cc98080 ------------3
printf("&p: %p\n", &p);//&p: 0x7ffc6cc981a0 ------------4
printf("&a1: %p\n", &a1); // &a1: 0x7ffc6cc980c0 /on stack, that's no problem …Run Code Online (Sandbox Code Playgroud) 我有一个int指向另一个地址的指针int。
当使用格式说明符打印指针时%p(如 Stack Overflow 上的许多答案所建议的那样),它以十六进制表示形式打印。
如何用十进制表示打印指针的值?
代码示例
我想出了一个可以%zu从这个答案中使用的人。
int i = 1;
int *p = &i;
printf("Printing p: %%p = %p, %%zu = %zu\n", p, p);
Run Code Online (Sandbox Code Playgroud)
当我使用https://onlinegdb.com/EBienCIJnm运行该代码时
warning: format ‘%zu’ expects argument of type ‘size_t’, but argument 3 has type ‘int *’ [-Wformat=]
Printing p: %p = 0x7ffee623d8c4, %zu = 140732759529668
Run Code Online (Sandbox Code Playgroud)
有没有办法printf使用十进制表示的指针值,而没有编译器警告?
我尝试在高级 R中实现该示例 ,以查看有多少名称指向某个位置。正如作者所说
\n\n\n请注意,如果您\xe2\x80\x99 使用 RStudio,
\nrefs()将始终返回 2:环境浏览器会引用您在命令行上创建的每个对象。
然而,就我而言,即使我已经清除了全局环境,也refs()总会返回65535
library(pryr)\nx <- 1:10\nc(address(x), refs(x))\n\n## "0x1d931f32d68" "65535" \nRun Code Online (Sandbox Code Playgroud)\n这是什么意思?
\n我们知道每条指令都转换为基址+偏移量,并且偏移量最大大小设置为4K(4096)。如果我的程序大小超过 4k 怎么办?
Line 1 : Base + 1 ,
Line 2 : Base + 5 ,
.
.
.
.,
Line x : base + 4090
Run Code Online (Sandbox Code Playgroud)
当指令超出页面大小 4096 时,如何对第 x 行开始进行寻址(如基址 + 偏移量)?
从 X 行开始的指令是如何组装的?我们是否需要将基地址更改为保存指令的下一页的开头?