繁体   English   中英

C 中的内存多态切片 function

[英]A memory-polymorphic slice function in C

想象一个返回数组一部分的 array_slice 方法。 还想象一下,您的程序正在使用多个 memory 分配策略,例如 Boehm、引用计数、池、分配/释放。 是否有一种惯用的或有点非人为的方式来执行此 array_slice function 以与 memory 分配无关的方式?

上下文的小代码片段。

typedef struct array array;
struct array {
    size_t length;
    uintptr_t* thing;
};
array array_slice(array old, int offset)
{
    size_t new_length = old.length - offset;
    array new = {
        .length = new_length,
        // TODO: This line needs to use same allocation strategy as for argument "old"
        .thing = malloc(sizeof(uintptr_t) * new_length)
    };
    size_t j = 0;
    for (size_t i = offset; i < old.length; i++) {
        new.thing[j] = old.thing[i];
        j++;
    }
    return new;
}

一种解决方案是让数组结构携带一个 function 指针和其他信息。 另一个可能使用_Generic? 打开建议或链接。 :) 谢谢。

一个问题是每个 memory 分配策略都需要稍微不同的仪式,比如引用计数需要增加或减少计数器,池需要传递一个指向已使用池 object 的指针,正常的 malloc 需要在正确的地方释放。

对于动态多态性,您可以定义一个抽象的“分配器”class:

struct Allocator {
    void *(*alloc)(struct Allocator *, size_t);
    void (*dealloc)(struct Allocator *, void *);
}
extern struct Allocator *malloc_allocator;
/* other allocator types here */

像这样的实现

void *malloc_alloc(struct Allocator *, size_t sz) {
    return malloc(sz);
}
void malloc_dealloc(struct Allocator *, void *ptr) {
    return free(ptr);
}

static struct Allocator malloc_alloc_obj = { malloc_alloc, malloc_dealloc };
struct Allocator *malloc_allocator = &malloc_alloc_obj;

您可以类似地定义其他分配器类型——那些需要额外数据的分配器类型 cn 定义一个私有结构,该结构以struct Allocator字段开头,后面有额外数据。 然后你只需要添加一个指向你的struct Array的指针。

C 没有提供实现 static 多态性的好方法。 你可以用宏伪造它,但结果非常脆弱。

想象一个返回数组一部分的 array_slice 方法

您可能在这里使用了错误的抽象。 array所有用户实际上都需要拥有切片中元素的副本吗?

将“切片”与底层 memory 的复制和所有权分开将使您可以非常便宜地制作和传递切片,并且当实际需要副本时,该副本的所有者可以决定哪种 memory 分配策略最适合该特定复制。

C++中,这个轻量级切片由std::span class 实现。

您的struct array可以保持完全相同, thing的区别是它指向其他人拥有的 memory。 array_slice变得更加简单和便宜:

array array_slice(array old, int offset)
{
    assert(offset <= old.length); 
    array new = {
        .length = old.length - offset,
        .thing = old.thing + offset;
    };
    return new;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM