C语言中的placement new等价物

4

在C语言中,是否有类似于C++的placement new的等效物?也就是说,在指定位置构造对象是否可行?能否使用realloc()实现这一功能?

4个回答

11

Placement new(定位 new)简单地跳过分配并在预先分配的内存中构造对象。由于 C 缺少构造函数,因此不需要使用定位 new。我想等效的方法可能是指针类型转换,因为一旦您拥有指针,您就可以像存在对象一样进行操作。

从共享内存池雕刻不同类型的对象的示例:

char *pool = (char *) malloc( 1000 );
char *pen = pool;

foo *obj1 = (foo *) pen;
pen += sizeof (foo);

bar *obj2 = (bar *) pen;
pen += sizeof (bar);

/* etc */
当然,在这样做的时候,您要承担将正确的指针传递给free,并照顾好对齐要求的责任,就像在C++中使用放置new一样。

吹毛求疵:“你可以假装一个对象存在。” C语言并没有真正的对象,它只有值。 - cdhowie
1
@cdhowie:ISO C标准在很多地方都使用“对象”这个术语。 - netcoder
1
@cdhowie: C99,§3.14/1:“对象是执行环境中的数据存储区域,其内容可以表示值”。 - Jerry Coffin
当然可以。但问题是关于C++对象的,这两者确实是不同的东西。在回答中使用该术语似乎有些令人困惑,因为它的含义与原始问题中的含义不同。但如果只有我这么认为,那我就让步了。 - cdhowie
1
@cdhowie C++中使用“对象”一词的含义与C语言完全相同。§1.8/1提供了定义:“对象是存储区域。”(请注意,这个定义之所以适用,是因为在C和C++中,不允许进行指针算术运算,从一个整个对象(根据任何存储方案分配)到另一个对象。) - Potatoswatter
显示剩余2条评论

3

由于C语言没有类似于构造函数的东西,你可以直接取地址并将其强制转换为所需类型的指针。当然,你需要确保正确的对齐方式,否则可能会失败(但在C++中使用放置new时也是如此)。


2

C语言中不存在“placement new”。然而,您可以声明一个指针并使其指向内存中的任何内容:

char *pointer = 0x12345678;

以上指针现在指向地址为0x12345678的任何内容。

这种情况经常在嵌入式系统中出现,其中某些设备位于内存中的特定位置。


1
在C语言中以便携的方式实现这一点的典型方法是:
#define X (*(int*)0x12345678u) // where 0x12345678 is a specific address 

// you can now use the int 'X' as any other type of variable:

X = 5;

if (X == SOMETHING)

假设地址0x12345678包含适合int类型的有效内存,并且您可以直接访问。具有虚拟内存的系统可能不允许直接访问。

在嵌入式系统中,像上面这样的声明通常用于定义硬件寄存器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接