C 在静态库中使用全局变量

C 在静态库中使用全局变量,c,memory-leaks,static-libraries,C,Memory Leaks,Static Libraries,我正在用纯C编写一些代码,RHEL 5.5 x64,gcc版本4.1.2 20080704(Red Hat 4.1.2-48) 我有一个使用2个静态库编译的可执行文件。它们中的每一个都使用一些全局(对于给定的库)数组变量(例如,在某个.c文件中,我有一个 char var1[VAR_SIZE1];,然后在库的其他.c文件中使用extern char var1[VAR_SIZE1];,第二个库的情况也一样)。 每个库都放置在可执行源目录的子目录中。 我开始注意到一个库可以将其数据放在另一个库的内存

我正在用纯C编写一些代码,RHEL 5.5 x64,gcc版本4.1.2 20080704(Red Hat 4.1.2-48)

我有一个使用2个静态库编译的可执行文件。它们中的每一个都使用一些全局(对于给定的库)数组变量(例如,在某个.c文件中,我有一个
char var1[VAR_SIZE1];
,然后在库的其他.c文件中使用
extern char var1[VAR_SIZE1];
,第二个库的情况也一样)。 每个库都放置在可执行源目录的子目录中。 我开始注意到一个库可以将其数据放在另一个库的内存中。为了发现发生了什么,我定义了一个指向第三个lib中一个变量的void指针(两个lib都使用lib3),在lib1中为该指针分配了一个地址,并查看了lib2中的地址。 我现在看到的是:

char var1[1000]; /*please mind the length*/
extern void* ptr_to_var2;
printf("var1 addr is %p, var2 addr is %p\n", (void*)&var1, ptr_to_var2);
此代码生成

var1地址为0xa11b00,var2地址为0xa11e00

如您所见,var1应该在地址0xa11ee8处结束,var2的头在var1内存中。 我做错了什么?在静态libs中使用全局变量有任何限制吗?我不能将这些变量定义为静态变量,因为它们在每个库中的许多文件中都使用,而使这些变量成为动态变量是一项艰巨的工作(有几十个这样的变量)

当然,ptr_to_var2已初始化。到底发生了什么

<lib3>
void* ptr_to_var2;

<lib2>
#include "hdr_with_my_struct_name_definition.h"
my_struct_name var2[5];
extern void* ptr_to_var2;

int func2(){
   ptr_to_var2=(void*)&var2;
   var2[0].fld1=12345;
   return 1;
}

<lib 1>
#include "hdr_with_my_struct_name_definition.h"
char var1[1000];
extern void* ptr_to_var2;

int func1(){
   my_struct_name *temp_var_2=(my_struct_name*)ptr_to_var2;
   printf("%d", temp_var_2[0].fld1);
   memset(var1, '\0', sizeof(var1);
   printf("%d", temp_var_2[0].fld1);
   return 1;
}

<binary>

main(){
   func2();
   func1();
   return;
}

void*ptr_至_var2;
#包括“hdr\u与我的结构名称\u定义.h”
我的结构名称var2[5];
外部无效*ptr_至_var2;
int func2(){
ptr_to_var2=(void*)&var2;
var2[0].fld1=12345;
返回1;
}
#包括“hdr\u与我的结构名称\u定义.h”
char var1[1000];
外部无效*ptr_至_var2;
int func1(){
my_struct_name*temp_var_2=(my_struct_name*)ptr_to_var2;
printf(“%d”,临时变量2[0].fld1);
memset(var1,'\0',sizeof(var1);
printf(“%d”,临时变量2[0].fld1);
返回1;
}
main(){
func2();
func1();
返回;
}
所有这些都会带来回报 12345 0

在这种情况下,您试图将
ptr\u的值打印到\u var2
而不是它的实际地址。由于此变量尚未初始化,其值是随机的,可以是任意值

#include<stdio.h>

char v[1000];

void *p1;

int main() {

    printf ("var1 %p, var2 %p  &var2 %p\n", &v[0], p1, &p1);

    return 0;
}

使用
extern
子句,您告诉编译器在链接时解析该符号。链接后,在二进制文件中只有一个名为
ptr_to_var
的符号。当然,您必须确保它在某个地方被初始化。在您粘贴的代码中,我们无法知道它是否被初始化。虽然看起来你没有


顺便说一句,尝试对库进行
nm
。您将看到指定为
extern
的符号未定义(大写u),但在该库或对象文件中确实定义了它(即,声明时没有
extern
子句)。

会使它们静态并“导出”通过专用的“get()”将其删除函数,返回指向它们的指针,帮助?通常的限制是不应该有多个全局对象共享同一个名称。可能有一些工具可以更改编译库中的符号名称。这在理论上是可能的,但这些变量的数量非常多。当然,它们都有不同的名称s(事实上,我有证据表明这两个名称对应“余额”和“fld54”)。
#include<stdio.h>

char v[1000];

void *p1;

int main() {

    printf ("var1 %p, var2 %p  &var2 %p\n", &v[0], p1, &p1);

    return 0;
}
var1 0x601040, var2 (nil)  &var2 0x601428