C 全局结构的数组元素位于不一致的位置

C 全局结构的数组元素位于不一致的位置,c,arrays,struct,C,Arrays,Struct,我正在开发一个C程序,它最初将大量配置信息读入一个全局结构,然后在所有源文件中共享。结构按以下方式定义: struct globalConfigDM { int controllerSocket; int controllerPort; int dfDmToDb; char **ocamsL0FitsKeywords; char **ocamsL0FitsTypes; char **ocamsL0DatabaseFields; int

我正在开发一个C程序,它最初将大量配置信息读入一个全局结构,然后在所有源文件中共享。结构按以下方式定义:

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头的散乱副本可能会更快。但最终,您应该进行一次完整的重建,以确保没有从头文件的早期版本中得到遗留的对象文件。