我试图用指针理解一些东西,所以我写了这段代码:
#include <stdio.h>
int main(void)
{
char s[] = "asd";
char **p = &s;
printf("The value of s is: %p\n", s);
printf("The direction of s is: %p\n", &s);
printf("The value of p is: %p\n", p);
printf("The direction of p is: %p\n", &p);
printf("The direction of s[0] is: %p\n", &s[0]);
printf("The direction of s[1] is: %p\n", &s[1]);
printf("The direction of s[2] is: %p\n", &s[2]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用gcc编译时我得到以下警告:
$ gcc main.c -o main-bin -ansi -pedantic -Wall -lm
main.c: In function ‘main’: …Run Code Online (Sandbox Code Playgroud) 在C中,我想使用printf来显示指针,以便它们正确排列,我想用0填充它们.
我的猜测是,正确的方法是:
printf("%016p", ptr);
这有效,但是这个gcc抱怨以下消息:
warning: '0' flag used with ‘%p’ gnu_printf format
我已经谷歌搜索了一下,以下主题是关于同一主题,但并没有真正给出解决方案.
http://gcc.gnu.org/ml/gcc-bugs/2003-05/msg00484.html
阅读它,似乎gcc抱怨的原因是我建议的语法没有在C99中定义.但我似乎无法找到任何其他方式以标准批准的方式做同样的事情.
所以这是双重问题:
Cosider以下代码:
class Foo
{
Monster* monsters[6];
Foo()
{
for (int i = 0; i < 6; i++)
{
monsters[i] = new Monster();
}
}
virtual ~Foo();
}
Run Code Online (Sandbox Code Playgroud)
什么是正确的析构函数?
这个:
Foo::~Foo()
{
delete [] monsters;
}
Run Code Online (Sandbox Code Playgroud)
或这个:
Foo::~Foo()
{
for (int i = 0; i < 6; i++)
{
delete monsters[i];
}
}
Run Code Online (Sandbox Code Playgroud)
我目前有最重要的构造函数,一切都在工作,但当然我看不出它是否恰好泄漏...
就个人而言,我认为考虑到我在做什么,第二个版本更合乎逻辑.无论如何,这样做的"正确"方法是什么?
在实现移动构造函数和移动赋值运算符时,通常会编写如下代码:
p = other.p;
other.p = 0;
Run Code Online (Sandbox Code Playgroud)
隐式定义的移动操作将使用以下代码实现:
p = std::move(other.p);
Run Code Online (Sandbox Code Playgroud)
这将是错误的,因为移动指针变量并没有将其设置为null.这是为什么?是否有任何情况我们希望移动操作保持原始指针变量不变?
注意:通过"移动",我不只是表示子表达式std::move(other.p),我的意思是整个表达式p = std::move(other.p).那么,为什么没有特殊的语言规则说"如果赋值的右侧是指针xvalue,则在赋值发生后将其设置为null."?
假设有一个指针,我们用NULL初始化它.
int* ptr = NULL;
*ptr = 10;
Run Code Online (Sandbox Code Playgroud)
现在,程序将崩溃,因为ptr没有指向任何地址,我们正在为其分配一个值,这是一个无效的访问.那么,问题是,操作系统内部会发生什么?是否发生页面错误/分段错误?内核甚至会在页面表中搜索吗?或者崩溃发生在那之前?
我知道我不会在任何程序中做这样的事情,但这只是为了知道在这种情况下OS或编译器内部发生了什么.这不是一个重复的问题.
当你学习C++时,或者至少当我通过C++ Primer学习它时,指针被称为它们指向的元素的"内存地址".我想知道这是多少.
例如,做两个元素*p1并*p2拥有属性,p2 = p1 + 1或者p1 = p2 + 1 当且仅当它们在物理内存中相邻时?
我正在研究以下代码片段:
#include <iostream>
#include <vector>
class myclass
{
public:
myclass()
{
std::cout << this << std::endl;
}
};
int main()
{
std::vector<myclass> v;
for(uint32_t i = 0; i < 10; i++)
v.push_back(myclass());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 编译代码g++ main.cpp。当我执行编译的二进制文件时,我得到:
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
0x7ffebb8f8cab
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么所有的this指针都是相同的?如果我创建同一类的 10 个不同对象,则应该有 10 个不同的this指针。正确的?
据我了解,我的代码当前正在使用相同对象的引用来填充向量v。然而,我想要的是 10 个不同的对象myclass。我怎样才能得到这个?此代码是一个较大项目的一部分,该项目在new和方面存在一些问题delete。所以我无法使用该 API。我做错了什么以及如何解决这个问题?
我不明白指针在for循环中的作用.什么是*p在下面的循环呢?
char str[128] = "Some Text";
char *p;
for (p = str; *p /*what does this mean?*/; p++)
{
// Code
}
Run Code Online (Sandbox Code Playgroud)
我确实了解其余的,但为什么不*p喜欢p > 3或类似的东西?
为什么一个人?
为什么这样写?
大图:我有一个带有功能的模块和一个带有这些功能的程序和功能的模块.
当我组合两个函数时(来自函数的模块接口):
double f1(double alpha, double x);
double f2(double beta, double x);
Run Code Online (Sandbox Code Playgroud)
在几个方面,(其中一个是添加):
double OP_Addition(double (*f)(double,double) , double (*g)(double,double), double param1, double param2, double x);
Run Code Online (Sandbox Code Playgroud)
以下(部分)实现没有问题:
z1 = (*f)(param1, x);
z2 = (*g)(param2, x);
y = z1 + z2;
return y;
Run Code Online (Sandbox Code Playgroud)
但是当我想返回指向"新"函数的指针时,类似于:
void *OP_PAdd( double (*f)(double,double), double param3 );
Run Code Online (Sandbox Code Playgroud)
我无法让它正常工作,也没有做出正确的"通话".我想在其他函数中使用输出"function"作为输入.
我和一些人说过这个论点,即C出界指针会导致未定义的行为,即使它们没有被解除引用.例:
int a;
int *p = &a;
p = p - 1;
Run Code Online (Sandbox Code Playgroud)
这里的第三行将导致未定义的行为,即使p永远不会被解除引用(*p从未使用过).
在我看来,如果没有指针被使用,C会检查指针是否超出界限听起来有点不合逻辑(就像有人会检查街上的人,看看他们是否携带枪支以防他们进入他的房子.理想的做法是在人们即将进入房屋时对他们进行检查.我认为如果C检查,那么会发生很多运行时开销.
另外,如果C真的检查OOB指针那么为什么这不会导致UB:
int *p; // uninitialized thus pointing to a random adress
Run Code Online (Sandbox Code Playgroud)
在这种情况下,即使p指向OOB地址的机会很高,为什么也不会发生任何事情.
加:
int a;
int *p = &a;
p = p - 1;
Run Code Online (Sandbox Code Playgroud)
说&a是1000. p评估第三行后的价值是:
p可能在其他地方取消引用并导致真正的问题.因为我认为"第三行被称为未定义的行为"首先是因为未来可能会使用该OOB指针(解除引用),随着时间的推移,人们将其视为一种未定义的行为.现在,值p是100%996还是未定义的行为或其值将是未定义的?