C 全局结构的数组元素位于不一致的位置
我正在开发一个C程序,它最初将大量配置信息读入一个全局结构,然后在所有源文件中共享。结构按以下方式定义:C 全局结构的数组元素位于不一致的位置,c,arrays,struct,C,Arrays,Struct,我正在开发一个C程序,它最初将大量配置信息读入一个全局结构,然后在所有源文件中共享。结构按以下方式定义: struct globalConfigDM { int controllerSocket; int controllerPort; int dfDmToDb; char **ocamsL0FitsKeywords; char **ocamsL0FitsTypes; char **ocamsL0DatabaseFields; int
struct globalConfigDM {
int controllerSocket;
int controllerPort;
int dfDmToDb;
char **ocamsL0FitsKeywords;
char **ocamsL0FitsTypes;
char **ocamsL0DatabaseFields;
int ocamsL0KeyCount;
char ocamsL0KeyLocation[300];
char **ocamsL1FitsKeywords;
char **ocamsL1FitsTypes;
char **ocamsL1DatabaseFields;
int ocamsL1KeyCount;
char ocamsL1KeyLocation[300];
char **ovirsFitsKeywords;
char **ovirsFitsTypes;
char **ovirsDatabaseFields;
int ovirsKeyCount;
char ovirsKeyLocation[300];
char databaseName[50];
char databaseUser[50];
char databasePassword[50];
char pcamL0Dir[300];
char pcamL1Dir[300];
char mcamL0Dir[300];
char mcamL1Dir[300];
char scamL0Dir[300];
char scamL1Dir[300];
char ncamL0Dir[300];
char ncamL1Dir[300];
char olaSciL0Dir[300];
char otesSciL0Dir[300];
char ovirsSciL0Dir[300];
char rexisSciL0Dir[300];
char ocamsHkDir[300];
char ovirsHkDir[300];
char otesHkDir[300];
char olaHkDir[300];
char rexisHkDir[300];
};
在我的一个源文件中,我声明了结构:
struct globalConfigDM gconf代码>
在其他源文件的头文件中,我用extern声明:
extern结构globalConfigDM gconf代码>
当我运行程序时,我遇到了问题,因为全局结构的各个字段的地址与主文件的地址不同,而与其他C文件的地址不同,即在少量字节上移位。奇怪的是,全局结构本身的地址在相同的文件中保持不变。我在程序中插入了两行日志,如下所示:
logWarn("In datamoverThread(), dm.c, &gconf.databaseUser is %p", &gconf.databaseUser);
logWarn(" And &gconf is %p", &gconf);
[WSDM@2014-06-19T12:11:38-07:00] In globalConfig(), config.c, &gconf.databaseUser is 0x78395a
[WSDM@2014-06-19T12:11:38-07:00] And &gconf is 0x783540
[WSDM@2014-06-19T12:11:38-07:00] In main(), dm.c, &gconf.databaseUser is 0x783956
[WSDM@2014-06-19T12:11:38-07:00] And &gconf is 0x783540
[WSDM@2014-06-19T12:11:38-07:00] In runDM(), dm.c, &gconf.databaseUser is 0x783956
[WSDM@2014-06-19T12:11:38-07:00] And &gconf is 0x783540
[WSDM@2014-06-19T12:11:38-07:00] In getNewCSock(), connect.c, &gconf.databaseUser is 0x78395a
[WSDM@2014-06-19T12:11:38-07:00] And &gconf is 0x783540
[WSDM@2014-06-19T12:11:48-07:00] In datamoverThread(), dm.c, &gconf.databaseUser is 0x783956
[WSDM@2014-06-19T12:11:48-07:00] And &gconf is 0x783540
我得到如下输出:
logWarn("In datamoverThread(), dm.c, &gconf.databaseUser is %p", &gconf.databaseUser);
logWarn(" And &gconf is %p", &gconf);
[WSDM@2014-06-19T12:11:38-07:00] In globalConfig(), config.c, &gconf.databaseUser is 0x78395a
[WSDM@2014-06-19T12:11:38-07:00] And &gconf is 0x783540
[WSDM@2014-06-19T12:11:38-07:00] In main(), dm.c, &gconf.databaseUser is 0x783956
[WSDM@2014-06-19T12:11:38-07:00] And &gconf is 0x783540
[WSDM@2014-06-19T12:11:38-07:00] In runDM(), dm.c, &gconf.databaseUser is 0x783956
[WSDM@2014-06-19T12:11:38-07:00] And &gconf is 0x783540
[WSDM@2014-06-19T12:11:38-07:00] In getNewCSock(), connect.c, &gconf.databaseUser is 0x78395a
[WSDM@2014-06-19T12:11:38-07:00] And &gconf is 0x783540
[WSDM@2014-06-19T12:11:48-07:00] In datamoverThread(), dm.c, &gconf.databaseUser is 0x783956
[WSDM@2014-06-19T12:11:48-07:00] And &gconf is 0x783540
main()函数包含在dm.c中,它在0x783956中找到gconf.databaseUser
,但其他文件config.c和connect.c在0x78395a中找到相同的字段;但是,所有文件都能够在同一地址找到gconf
本身
我已经花了相当多的时间在gdb里四处闲逛,对于为什么会发生这种情况,我感到相当困惑。我以前没有问过这样的问题,所以如果我含糊其辞,我很抱歉,我很乐意提供任何有帮助的信息
提前谢谢
编辑:根据请求,这里是connect.h和dm.h的全部代码,这两个源文件的头文件位于不同地址的struct字段
连接
\ifndef CONNECT\u DM\H
#定义CONNECT_DM_H
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“prodqueue.h”
#包括定义结构的“config.h”//
void receiveAllCommands(void);
void getNewCsockConnection(void);
作废状态(作废);
int-sendHeartbeat(void);
void sendResults(未签名的char dest、int failure、const product*prod);
#恩迪夫
dm.h
\ifndef DM\u H
#定义DM_H
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“oci.h”
#包括“processing.h”
#包括“prodqueue.h”
#包括“connect.h”
#包括定义结构的“config.h”//
int-handleOpts(int-argc,char*argv[]);
void*datamoverThread(void*semNumber);
void runDatamover(int-debug);
int moveFile(产品*prod);
int performDatamoverWork(常数产品*prod,OCISvcCtx**svchp,
OCISMT**stmthp,OCIRROR**errhp);
#恩迪夫
在包含结构定义的包含文件之前,源文件的宏存在一些差异。
结果证明这毕竟是一个包装指令。有人在一个旧的、旧的系统头中使用了#pragma pack(1)
,但没有用#pragma pack(push | pop)
包装它,所以它通过#include
传播到我的代码中
我发现这篇文章基本上总结了我今天的经历:
非常感谢那些帮助过我的人 您的任何标题中是否有任何#pragma pack
、#pragma align
或类似的指令?@nbrooks3:好的-最后一个问题,然后我就被难住了-在#include
之前的connect.c
中是否有任何异常的地方,它会拉入struct globalConfigDM
声明,例如,任何#定义或任何不寻常的东西?我会问显而易见的问题(但希望答案是“是”):你重新编译了所有东西吗?另一方面,名称config.h
被autoconf
和相关系统用来保存配置信息,因此它不是头名称的最佳选择,但是如果您不遵守这一点,您将看到一组完全不同的问题(编译错误)。您是否已验证目录系统中没有两个(略有不同)版本的config.h
?是否有人将config.h
的旧副本复制到一个目录中,然后更改了两个版本中的一个,但不是两个版本都更改了?按照JL的思路,dbUser甚至不是您共享的版本中的一个字段。您是否确定所有编译都是最新的,并且不是某些文件引用了旧版本的结构,这可能解释了添加字段时4字节大小的小差异。因此,它毕竟是一个打包指令。有人在一个旧的、旧的系统头中使用了#pragma pack(1)
,但没有用#pragma pack(push | pop)
包装它,所以它通过#include
传播到我的代码中。非常感谢那些帮助过我的人@保罗,除了我自己的头球,你还应该看一下头球,你马上就得到了答案@JonathanLeffler感谢sizeof(struct)提示和所有其他帮助。我会在8小时结束后发布答案。对不起,我不太明白你的意思。如果你的意思与Paul上面的评论相似,我没有任何#define
s出现在#之前,包括任何文件中的s。Jim说的是,尽管你的意图是好的,但你的目标代码中使用了两个不同版本的结构定义。根据您的系统有多大,删除每个对象文件并从头开始重建可能会更快,或者查找config.h头的散乱副本可能会更快。但最终,您应该进行一次完整的重建,以确保没有从头文件的早期版本中得到遗留的对象文件。