野(函数)指针

2009年2月22日 06:09

本来这个问题可以归为指针的一部分,野指针的管理和注意应该更加是必要的基础。

但野(函数)指针在嵌入式系统中还真是不多见,至少俺不那么多见。

简单说一下原理:

 

typedef int (* function)(int);

function类型的指针就可以指向:返回值为int类型,参数为int类型的函数;

例如:

 

#include <stdio.h>
typedef int (* function)(int);
static int printHex(int para)
{
                printf("para = [%x]\r\n", para);
                return 0;
}

int main(void)
{
        function p = printHex;
        p(10);
        return 0;
}

 

这是一段很简陋的代码,简单演示一下函数指针如何使用。实际情况中,往往p是A模块作为一个参数传递给B模块,在B模块中调用p(10),也就是常说的回调机制。

在一般情况下,printHex这个函数都是被分配在一个固定地址,尽管它会被static类的修饰来决定访问权限;但无论如何它在整个代码的生命周期中是存在的,即一般不会碰到p指针成为野指针的情况。但是要注意,如果printHex如果是在一个动态模块中,例如前面说到A模块中实现的printfHex,然后通过一个指针传给B,但在B执行之前,A模块就由于某种机制释放掉了。这个时候B中的指针就成为野指针。如果再次访存就会导致SIGSEGV.

一般的系统似乎都不会有这种问题,但在BREW平台上就会有。 BREW平台提供动态编译机制,来达到节省内存的目的。很类似PC上的虚拟内存的管理机制,用到的模块在运行时会被载入内存,在不用时就会从内存中移除。这样如果静态编译的模块通过函数指针调用动态模块中的注册函数的话,那就会。。。。。。

这种问题出现恶心的很。。 

2038年问题

2009年2月10日 05:51

晚上在cnBeta上看到了这个问题,居然碰到下午有同事问题time_t的类型,看看wiki吧。

估计能看到32位溢出,真是幸运,好期待我能看到64位溢出的情况(新的64位運算器可以記錄至約2900億年後的292,277,026,596年12月4日15:30:08,星期日(UTC))呢。。-_#

也谈数组与指针

2009年2月05日 05:08

看到wangcong写了关于数组和指针的问题,也想偷偷说两句。

文中讲到“a仅仅是个名字,它并不是指向数组第一个元素的整型指针,也不是一个数组类型!更为关键的是,它在内存中根本就不存在!!”这一点不是那么苟同。

我的理解是数组名a是存在的,就是第一个元素的地址。而数组长度为编译器指明了数组成员,也就指明了每一个元素的地址。当编译器根据数组名a来访问地址时,就是首地址a[0]的地址;访问内容时,由于是一个连续地址的数组空间因此会访问整个数组的内容。(为什么会被识别成为数组空间还不清楚,猜想可能碰到有符号指向的地址就认为数组空间停止了吧,无论栈上还是堆上,已分配的变量是尽量连续的)

19:         printf("%d\n", c[1]);

这一句其实就说明了数组和指针的不同之一:a[i]总是被编译器“翻译”成为*(a+1)这种形式,这里首先被承认的就是是a就是数组首地址,i偏移的就是i个数组元素类型所占空间的字节数。

我倒认为数组和指针的最大不同在于数组首地址是常量不可改变;而指针是可以随意修改的

如有错误,敬请指正。