好的,我们有一个名为incr
的函数,它只是将数字增加1,然后返回新值,但将指针作为参数:
int incr(int *arg)
{
*arg++;
return *arg;
}
因此,如果我们写下以下内容:
int main()
{
int i = 1, j = 0;
cout << j << endl;
int* p_i = &i;
j = incr(p_i); // changes both i and j
cout << i << ", " << j << endl; //should print 2, 2
return 0;
}
由于我们使用变量i
的指针作为参数,如果*p_i
函数内的incr
发生了某些事情,那么当i
时,incr
的变更将是永久的{1}}已完成。自从我们设置j=incr(i)
并且我们不返回p_i
本身,但其内容(现在是i
的2值),j
现在应该是2.但由于某种原因,结果如下:
1, -858993460
我根本就不明白为什么。也许我在这个洞指针/函数调用中理解了一些错误。任何帮助都会被扼杀
答案 0 :(得分:6)
这是一个operator precedence问题。
https://api.ipify.org/
的优先级高于operator++
,因此您递增地址,然后取消引用它。
operator*
将解决您的问题。
答案 1 :(得分:6)
*arg++;
将被解析为*(arg++);
,因为运算符++
优先于解除引用运算符*
。它将递增指针arg
,然后获取未初始化的递增指针的值。在这种情况下,您的程序可能会调用未定义的行为
您需要将其更改为(*arg)++;
。
答案 2 :(得分:2)
Postfix ++
的优先级高于一元*
,因此*arg++
正在解析为*(arg++)
- 而不是递增*arg
的结果{1}},您取消引用arg++
的结果,这不是您想要的结果。
您需要使用括号*
将arg
运算符与(*arg)++
明确分组。
答案 3 :(得分:2)
问题是在functopn中使用了不太合适的运算符(后递增)。:)
而不是
*arg++;
没有你期望的行为会更好写
++*arg;
此表达式与语句逻辑更加一致。
至于这个表达
*arg++;
然后使用它的函数等效于以下函数定义
int incr(int *arg)
{
int tmp = *arg;
arg++;
return *arg;
}
并且具有未定义的行为,因为变量arg
中的结果指针指向原始对象之外。
答案 4 :(得分:1)
试试这个 int incr(int * arg) { (* arg)+ = 1; return * arg; }
或者 也许
答案 5 :(得分:1)
从++
has precedence over *
开始,*arg++
等同于*(arg++)
并在读取指向未知内存的内存之前递增指针,这是未定义的行为。
您可以使用括号修复incr
函数:
int incr(int *arg)
{
(*arg)++;
return *args;
}
或使用前缀表示法:
int incr(int *arg)
{
return ++*arg;
}