地址空间库或流程

时间:2010-06-29 05:31:17

标签: c linux memory shared-libraries

我有一个基本的疑问。 我有一个使用共享库的进程。如果我在库中分配一些内存 然后它是哪个地址空间。 (图书馆或流程) 在我看来,它是进程地址空间,因为一旦附加了库,它就全部在进程地址空间中。

如果我错了,请纠正我。

由于 Arpit

4 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

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

进程只有一个地址空间,进程内的所有内容(主可执行文件,任何共享库和任何静态库)都共享单个地址空间。

虽然单个地址空间中可能存在多个堆,但glibc的实现方式只有一个标准堆(标准堆,我指的是通过malloc / free访问的堆)。这与Windows不同,其中可执行文件和dll可能各自都有自己的堆(尽管再次共享一个地址空间)。

答案 2 :(得分: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文件供你全部测试。

生成文件

default: libobject.a consumer1 consumer2

.c.o: %.c
    $(CC) -c -o $@ $<

libobject.a: object.o
    $(AR) r $@ object.o


object.o: object.c object.h

consumer1 consumer2: $@.o libobject.a
    $(CC) -o $@ $@.o -L. -lobject 

P.P.S:这只是一本指南!我还没有在这里测试过所有的代码,希望这一切都可以顺利运行,但是,如果我做了语法错误,请妥善解决。

答案 3 :(得分:0)

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

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

因此,无论在何处编写内存(进程或库),进程上下文都会确定内存的分配。