在静态库中使用全局变量

时间:2012-10-03 09:55:31

标签: 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];,然后在我使用extern char var1[VAR_SIZE1];的lib的其他.c文件中,与第二个lib相同的情况)。 每个库都放在它自己的可执行源目录的子目录中。 我开始注意到一个lib可以将其数据放在另一个lib的内存中。为了发现正在发生的事情,我已经定义了一个指向第三个lib中的一个变量的void指针(lib 3被两个lib使用),在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 addr为0xa11b00,var2 addr为0xa11e00

如您所见,var1应该以地址0xa11ee8结束,而var2的头部是INSIDE var1内存。 我究竟做错了什么?在静态库中使用全局变量有任何限制吗?我不能将这些变量定义为静态变量,因为它们在每个lib中的许多文件中使用,并且使这些变量动态是一项大工作(有很多这样的变量)。

P.S。当然,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;
}

所有这一切都会回归 12345 0

2 个答案:

答案 0 :(得分:1)

printf("var1 addr is %p, var2 addr is %p\n", (void*)&var1, ptr_to_var2);

在此,您尝试打印的ptr_to_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;
}

给出:

var1 0x601040, var2 (nil)  &var2 0x601428

答案 1 :(得分:0)

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

顺便说一下,尝试为库创建一个nm。您将看到指定为extern的符号为undefined(大写u),但该库或目标文件中确实定义的符号(即,没有extern子句声明)。