我是C的新手,我正在编写一个非常基本的函数,它将整数指针作为参数。在函数内部,必须创建一个浮点指针。此函数必须将整数指针的值赋给float,然后返回float。这是我目前的代码:
float * function(const int *x)
{
float *p = (float*)x;
return p;
}
但是这会导致在运行时读取的错误:“free():无效指针:0x00007fffc0e6b734”。我只想说,我很困惑。您可以提供的任何见解将非常感谢!
答案 0 :(得分:0)
成为C的新手,您熟悉scope of variables吗? (部分)变量作用域的简短版本是,如果你不做一些额外的东西,在函数中创建的变量只存在于该函数内。为什么这对你很重要:如果你返回一个指向你在一个函数内部创建的变量的指针(没有做那些额外的事情),那么指针将指向一个内存区域,该区域可能包含也可能不包含你赋给它的值。做你想做的事的一种方法是:
float *makefloat(int *x) {
// static keyword tells C to keep this variable after function exits
static float f;
// the next statement working from right to left does the following
// get value of pointer to int (x) by dereferencing: *x
// change that int value to a float with a cast: (float)
// assign that value to the static float we created: f =
f = (float) *x;
// make pointer to float from static variable: &f
return &f;
}
一般来说,我似乎看到更多函数接受指向要修改的变量的指针,然后在该函数中创建新值并将其分配给指针引用的内存区域。因为该内存区域存在于函数范围之外,所以不必担心范围和静态变量。关于静态变量的另一个很酷的事情是,下次调用该函数时,静态变量具有与函数上次退出时相同的值。在Wikipedia上解释。
对*
和&
的良好解释:Pointers in C: when to use the ampersand and the asterisk
答案 1 :(得分:0)
您的函数仅执行指针转换。表单的函数调用
q = function(p); /* p is a "const int *" pointer,
q is assignment comaptible with "float *". */
可以用表达式替换:
q = (float *) p;
本身,这没有任何伤害。问题出在您的计划的其他地方。
请注意,大多数类型惩罚,例如通过指针使用类型int
的表达式访问类型float
的对象,是C语言中的未定义行为。这不是在示例代码中进行的,但是事情朝这个方向发展;指针可能正在准备进行打字。
请注意int
和float
的大小不一定相同;这不是唯一的考虑因素。在这样的代码中:
int i = 42;
/* now treat i as a float and modify it sneakily */
*((float *) &i) = 3.14;
printf("i = %d\n", i);
printf
的输出仍然可以是42.优化编译器可以将i
放入机器寄存器,而可以在作为“后备存储”的内存位置执行偷偷摸摸的分配“对于i
,所以i
显示为未更改,因为printf
调用使用了寄存器缓存的副本。编译器不需要考虑对类型float
指定的对象的修改可能会影响类型i
的对象的值(即使它们具有相同的大小,因此没有通过转让完成的附带损害,如覆盖其他物品)。
在现实世界中,有时需要编写一个操作浮点对象的代码,就好像它们是整数一样:通常为unsigned int
个整数,以获取对float
的按位表示的访问权限。完成此操作后,您必须使用联合,或者可能使用编译器特定的功能,例如GCC的-fno-strict-aliasing
选项,这会导致编译器在类型惩罚时更加谨慎地进行优化。在这种代码中,您确保所有假设都是关于类型大小的保证,使用#ifdef
- s用于不同平台,可能基于从运行配置脚本中提取的值来检测平台功能。 / p>
毋庸置疑,这不是一个在初学者阶段学习C的好方法。