我有一個基本的疑問。 我有一個使用共享庫的進程。如果我在庫 中分配了一些內存,那麼它是哪個地址空間。 (Library or Process) 在我看來,它是進程地址空間,因爲一旦連接了庫,它都在進程地址空間中。地址空間庫或進程
如果我錯了,請糾正我。
感謝 Arpit
我有一個基本的疑問。 我有一個使用共享庫的進程。如果我在庫 中分配了一些內存,那麼它是哪個地址空間。 (Library or Process) 在我看來,它是進程地址空間,因爲一旦連接了庫,它都在進程地址空間中。地址空間庫或進程
如果我錯了,請糾正我。
感謝 Arpit
庫沒有自己的地址空間。它映射到某個進程並在其中執行。所以你是對的。共享庫的內存分配在正在使用它的進程內完成。
這聽起來像你可能會在地址空間和堆之間感到困惑。
進程只有一個地址空間,一個進程中的所有內容(主可執行文件,任何共享庫和任何靜態庫)都共享單個地址空間。儘管可能在單個地址空間中存在多個堆,但glibc的實現方式是隻有一個標準堆(標準堆,我指的是通過malloc/free訪問的堆)。這不同於Windows,可執行文件和dll可能都有自己的堆(儘管同樣是共享一個地址空間)。
庫本身沒有內存空間,因爲它不是正在運行的進程。共享庫的概念是共享代碼指令的副本,但不包含該代碼使用或生成的任何數據。
因此,例如,如果你的庫是用來管理一個動態分配的結構:
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:這是作爲僅作爲參考!我還沒有在這裏測試過代碼,希望它一切順利,但是,如果我犯了語法錯誤,請適當修復。
共享庫可以鏈接許多進程,並在這些進程的上下文中運行。
假設你有一個共享庫來發送http請求。瀏覽器進程和桌面應用程序都可以與該庫鏈接,但是進程上下文將使它們能夠發送獨立請求,儘管它們都加載了相同的庫。
因此,進程上下文決定內存分配,無論它在哪裏寫入(進程或庫)。