在ANSI C中,offsetof定义如下.
#define offsetof(st, m) \
((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))
Run Code Online (Sandbox Code Playgroud)
为什么这不会引发分段错误,因为我们正在取消引用NULL指针?或者这是某种编译器黑客,它看到只有偏移的地址被取出,所以它静态地计算地址而不实际解除引用它?这个代码也可以移植吗?
我在一些不同的函数中有一些代码看起来像这样:
void someFunction (int *data) {
data = (int *) malloc (sizeof (data));
}
void useData (int *data) {
printf ("%p", data);
}
int main () {
int *data = NULL;
someFunction (data);
useData (data);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
someFunction ()并useData ()在单独的模块(*.c文件)中定义.
问题是,虽然malloc工作正常,并且分配的内存可用someFunction,但一旦函数返回,相同的内存就不可用.
这里可以看到程序的示例运行,输出显示各种存储器地址.
有人可以向我解释我在这里做错了什么,以及如何让这段代码工作?
编辑:所以似乎我需要使用双指针来做这个 - 当我真的需要使用双指针时,我将如何做同样的事情?所以例如数据就是
int **data = NULL; //used for 2D array
Run Code Online (Sandbox Code Playgroud)
那么我是否需要在函数调用中使用三指针?
我的问题主要是关于术语以及如何解释标准。
比较指向对象的不等指针的结果是根据符合以下规则的偏序定义的:
(4.1) 如果两个指针指向同一个数组的不同元素,或者指向其子对象,则要求指向下标较高的元素的指针比较大。
(4.2) 如果两个指针递归地指向同一对象的不同非静态数据成员,或指向此类成员的子对象,则要求后面声明的成员的指针比较大,前提是这两个成员具有相同的访问控制( [class.access]),两个成员都不是零大小的子对象,它们的类也不是联合。
(4.3) 否则,两个指针都不需要比较大于另一个。
我对如何解释(4.3)有点困惑。这是否意味着这
#include <iostream>
int main() {
int x;
int y;
std::cout << (&x < &y);
std::cout << (&x < &y);
}
Run Code Online (Sandbox Code Playgroud)
是...
11或00。?
换句话说,我知道(4.3)确实适用于此,但我不确定其含义。当标准说“它可以是 A 或 B”时,这与说“它是未定义的”相同吗?
c++ pointers undefined-behavior comparison-operators language-lawyer
我的一个朋友从“理解和使用 C 指针 - Richard Reese,O'Reilly 出版物”中指出了第二个要点,我无法解释其中的第一句话。我错过了什么?
空指针
指向 void 的指针是一个通用指针,用于保存对任何数据类型的引用。指向 void 的指针的示例如下所示:
Run Code Online (Sandbox Code Playgroud)void *pv;它有两个有趣的特性:
- 指向 void 的指针将具有与指向 的指针相同的表示形式和内存对齐方式
char。- 指向 void 的指针永远不会等于另一个指针。但是,分配了一个
NULL值的两个空指针将是相等的。
这是我的代码,不是书中的代码,所有指针都具有相同的值并且相等。
#include <stdio.h>
int main()
{
int a = 10;
int *p = &a;
void *p1 = (void*)&a;
void *p2 = (void*)&a;
printf("%p %p\n",p1,p2);
printf("%p\n",p);
if(p == p1)
printf("Equal\n");
if(p1 == p2)
printf("Equal\n");
}
Run Code Online (Sandbox Code Playgroud)
输出:
0x7ffe1fbecfec 0x7ffe1fbecfec
0x7ffe1fbecfec
Equal
Equal
Run Code Online (Sandbox Code Playgroud) 我有一个家庭作业,要求我使用缓冲区溢出调用函数而不显式调用它.代码基本上是这样的:
#include <stdio.h>
#include <stdlib.h>
void g()
{
printf("now inside g()!\n");
}
void f()
{
printf("now inside f()!\n");
// can only modify this section
// cant call g(), maybe use g (pointer to function)
}
int main (int argc, char *argv[])
{
f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
虽然我不知道该怎么办.我想改变程序计数器的返回地址,以便它直接进入g()的地址,但我不知道如何访问它.无论如何,提示将是伟大的.
我更喜欢在任何地方使用引用,但是当你使用STL容器时,你必须使用指针,除非你真的想按值传递复杂的类型.我觉得很难转换回参考,这似乎是错误的.
是吗?
澄清...
MyType *pObj = ...
MyType &obj = *pObj;
Run Code Online (Sandbox Code Playgroud)
这不是'脏',因为你可以(即使只是在理论上,因为你先检查它)取消引用一个NULL指针?
编辑:哦,你不知道对象是否是动态创建的.
正如标题本身所提到的 - 为什么指向引用的指针是非法的,而反向在C++中是合法的?
谢谢.
打印指针时遇到问题.每次我尝试编译下面的程序时,我都会收到以下错误:
pointers.c:11: warning: format ‘%p’ expects type ‘void *’, but argument 2 has type ‘int *’
Run Code Online (Sandbox Code Playgroud)
我显然在这里遗漏了一些简单的东西,但是从我见过的类似代码的其他考试中,这应该是有效的.
这是代码,任何帮助都会很棒!
#include <stdio.h>
int main(void)
{
int x = 99;
int *pt1;
pt1 = &x;
printf("Value at p1: %d\n", *pt1);
printf("Address of p1: %p\n", pt1);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在学习golang,当我阅读描述Structures的章节时,我遇到了不同的方法来初始化结构.
p1 := passport{}
var p2 passport
p3 := passport{
Photo: make([]byte, 0, 0),
Name: "Scott",
Surname: "Adam",
DateOfBirth: "Some time",
}
fmt.Printf("%s\n%s\n%s\n", p1, p2, p3)
Run Code Online (Sandbox Code Playgroud)
虽然这些打印结构的值为
{ }
{ }
{ Scott Adam Some time}
,下面的代码用&符号打印,因为它是一个引用.
pointerp1 := &p3
fmt.Printf("%s", pointerp1)
pointerp2 := new(passport)
pointerp2.Name = "Anotherscott"
fmt.Printf("%s", pointerp2)
Run Code Online (Sandbox Code Playgroud)
&{ Scott Adam Some time}&{ Anotherscott }
请帮助我解决疑惑.
在用法中pointerp1 := &p3,pointerp1是引用变量to p3,它保存实际数据.同样,保存数据的实际变量是pointerp2什么?
使用这些不同类型的初始化的最佳方案是什么?