C :: 在函数中投递指针,丢失数据?



我有一个 C 语法 101 问题。 假设我有一个函数,它将一种指针作为参数并返回不同类型的指针,并且两个指针都指向调用函数中的相同数据。 例如:

#include <stdio.h>
float* convertPtr(const int *a){
return (float*)a;
}
int main() {
float *ptrF;
int x = 5;
ptrF = convertPtr(&x);
printf("%d ::converted to::  %fn", x, *ptrF);
return 0;
}

该程序的输出为:

5 ::converted to::  0.000000

所以我对此有点困惑。 原始数据是在main()中创建的,不会更改。convertPtr()函数永远不会更改数据,而应该只更改指针的类型。

我还注意到,当我在 GDB 上单步执行代码时,指针(地址本身)不会改变:

Breakpoint 1, main () at exp.c:9
9         int x = 5;
(gdb) p &x
$3 = (int *) 0x7fffffffe224
...continue to after calling convertPtr()...
(gdb) p ptrF
$4 = (float *) 0x7fffffffe224
(gdb)

然而,指向该数据的价值具有:

(gdb) p x
$8 = 5
(gdb) p *(&x)       // sanity check
$9 = 5
(gdb) p *ptrF
$10 = 7.00649232e-45
(gdb)

所以......到底是什么? 在我的 convertPtr() 函数之后,指针已被重新转换,但指针的值没有改变......然而,取消引用转换后的指针似乎指向垃圾数据。 (我假设。

有人在这里看到问题吗? 假设我必须修复我的功能;我该怎么做? 谢谢。。。

-居留权

PS:如果这是一个重复的问题,请道歉。 我搜索了大约一个小时的"C"、"指针"、"铸造"、"更改值",我拉出的帖子遍布地图。 有时最好直接提出您的问题。

在你的代码中

return (float*)a;

违反了严格的别名规则。int *float *不会相互别名,因此强制转换会使代码无效

intfloat有不同的对齐要求,因此基本上您不能通过指向float的指针引用为int保留的内存位置(反之亦然),并期望一切都到位。

引用标准的相关部分,第 §6.5/P7 章

对象的存储值只能由具有以下 以下类型:88)

— 与对象的有效类型兼容的类型,

— 与对象的有效类型兼容的类型的限定版本,

— 一种类型,它是与 的有效类型对应的有符号或无符号类型 对象

— 一种类型,它是与 的限定版本相对应的有符号或无符号类型 对象的有效类型,

— 包含上述类型之一的聚合或联合类型 成员(递归地包括子聚合或包含的联合的成员),或

— 字符类型。

以及更多章节 §6.3.2.3/P7

指向对象类型的指针

可以转换为指向其他对象类型的指针。如果 生成的指针未正确对齐68)对于引用的类型,行为为 定义。[....]

最新更新