函数指针使用问题

问题:使用函数指针调用函数程序跑飞。

场景描述:

在A文件内正常调用函数指针可以初始化,可以调用。

到main函数内初始化的test无法正常使用函数指针。

/***************************************/
a.h 文件
#ifndef A_H
#define A_H
#include "x.h"
typedef struct
{
    bool value;
    void (*p)(void);  
}struct_a;

void init(struct_a* s);
#endif
/***************************************/
a.c文件
#include "a.h"
void a_func(void)
{
    xxxxx;
}

void init(struct_a* s)
{
    s->value = 1;
    s->p = a_func;
}


/***************************************/
问题就和x.h有关
x.h文件内容
#ifndef x_H
#define x_H

#include "a.h"
#pragma pack(1)
#endif

/***************************************/
main.c文件
#include "x.h"
#include "a.h"

struct_a  test;

int main()
{
    init(&test);
    test.p();  //这边程序跑飞
    return 0;
}

问题解决

后查看内存,发现内存中保存数据如下表,函数入口地址是0x080067d0。

仿真函数指针p的内容为8;

0x2000, 01980x0006,7d00
ox2000, 019c0x0000, 0008

最后发现和地址对齐有关#pragma pack(1) 1

删除#pragma pack(1) 1 程序可以在main.c内正常调用。

问题到这解决了一半,因为只解释了问什么main不能调用。解决方法也只是删除#pragma pack(1)

剩下一个问题是为什么a文件可以正常使用p指针?

返回重新查看头文件发现,a的头文件包含x的头文件,x的头文件也包含了a的头文件。

同时main文件包含了x的头文件。

这里面涉及到预处理的知识,并不是很懂,大胆猜测一下,头文件重复包含的情况下。

(1)处理到main.c的时候,先处理x.h,发现x.h包含了a.h,继续处理a.h,此时发现重复包含x.h,直接跳过了,然后发现了struct_a,此时#pragma pack(1) 并没有生效。处理完a.h以后回到x.h,#pragma pack(1)才生效。所以main文件内的struct_a是没有按照一字节对齐去解析的。

(2)处理到a.c的时候,#pragma pack(1)已经生效了,所以在a.c的作用域范围内struct_a是按照1字节解析了,所以p指针在a.c内能正常使用,而在main.c内无法正常使用。

这地方也不是很懂,大概理解到这把,最后只能说,包含头文件的时候小心点,非必要不包含!!!大部分情况下extern下可以了。还有注意下#pragma pack(1)的使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值