2010-06-29 69 views
1

我有一个基本的疑问。 我有一个使用共享库的进程。如果我在库 中分配了一些内存,那么它是哪个地址空间。 (Library or Process) 在我看来,它是进程地址空间,因为一旦连接了库,它都在进程地址空间中。地址空间库或进程

如果我错了,请纠正我。

感谢 Arpit

回答

5

库没有自己的地址空间。它映射到某个进程并在其中执行。所以你是对的。共享库的内存分配在正在使用它的进程内完成。

2

这听起来像你可能会在地址空间和堆之间感到困惑。

进程只有一个地址空间,一个进程中的所有内容(主可执行文件,任何共享库和任何静态库)都共享单个地址空间。尽管可能在单个地址空间中存在多个堆,但glibc的实现方式是只有一个标准堆(标准堆,我指的是通过malloc/free访问的堆)。这不同于Windows,可执行文件和dll可能都有自己的堆(尽管同样是共享一个地址空间)。

1

库本身没有内存空间,因为它不是正在运行的进程。共享库的概念是共享代码指令的副本,但不包含该代码使用或生成的任何数据。

因此,例如,如果你的库是用来管理一个动态分配的结构:

object.h

struct object_struct { 
     char *name; 
     int foo; 
     int bar; 
}; 

typedef struct object_struct * object_t; /* opaque pointer */ 

object_t new_object (char *name, int foo, int bar); 
void delete_object(object_t); 
int dump_object(object_t); 

object.c

#include <stdio.h> 
    #include "object.h"  

    object_t new_object (char *_name, int foo, int bar) { 
     object_t _p = malloc(sizeof(object_t); 
     if (!_p) 
      return NULL; 
     _p->foo = foo; _p->bar = bar; 
     _p->name = strdup(_name); 
     return _p; 
    } 

    void delete_object(object_t p) { 
     if(_p->name) 
      free(_p->name); 

     if(_p) 
      free(_p); 
    } 

    int dump_object(object_t p) { 
     FILE * fp = fopen(p->name, "w"); 
     if (!fp) 
      return -1; 
     fprintf(fp, "foo: %d\nbar: %d\n", p->foo, p->bar); 
     fclose(fp); 
     return 0; 
    } 

而且你两个程序consumer1.c和consumer2.c使用该库对象,如下所示:

consumer1.c

#include "object.h" 

int main() { 
     object_t o = new_object("consumer1.txt", 1, 2); 
     dump_object(o); 
     delete_object(o); 
     return 0; 
} 

consumer2.c

#include "object.h" 

int main() { 
     object_t o = new_object("consumer2.txt", 1, 2); 
     dump_object(o); 
     delete_object(o); 
     return 0; 
} 

对所有意图和目的,对象库的这两个节目不会有任何共同的数据或共同记忆或公共空间。

P.S .:假设gcc和gnu make,这里有一个make文件供你测试一切。

的Makefile

default: libobject.a consumer1 consumer2 

.c.o: %.c 
    $(CC) -c -o [email protected] $< 

libobject.a: object.o 
    $(AR) r [email protected] object.o 


object.o: object.c object.h 

consumer1 consumer2: [email protected] libobject.a 
    $(CC) -o [email protected] [email protected] -L. -lobject 

P.P.S:这是作为仅作为参考!我还没有在这里测试过代码,希望它一切顺利,但是,如果我犯了语法错误,请适当修复。

0

共享库可以链接许多进程,并在这些进程的上下文中运行。

假设你有一个共享库来发送http请求。浏览器进程和桌面应用程序都可以与该库链接,但是进程上下文将使它们能够发送独立请求,尽管它们都加载了相同的库。

因此,进程上下文决定内存分配,无论它在哪里写入(进程或库)。