1

是否可以在 C 程序中使用“临时字符串对象”?

例如,我有一个相当大的 char * 对象数组(结构的一部分),它们当前正在使用堆分配的内存。我有机会减少程序的内存使用量,因为这些名称中的大多数都可以在不使用显式字符数组的情况下确定(尽管并非所有名称都可以)。

在 C++ 中,我只需创建一个返回 std::string 对象(按值)并完成它的 API。在 C 语言中,我无法想出令我兴奋的解决方案。建议?


这是一些代码,如要求:

struct FOO {
    char *name;
    ...
 };

extern FOO* global_foo_array; /* in .h file */

void setup_foo(void) {
    int i;
    global_foo_array = (FOO*) malloc ( get_num_foo() * sizeof(FOO) );

    for (i = 0; i < get_num_foo_with_complex_name(); ++i) {
        global_foo_array.name[i] = malloc ( ... );
    }

    for (i = get_num_foo_with_complex_name(); i < get_num_foo(); ++i) {
        char buf[100];
        sprintf( buf, "foo #%d", i );
        global_foo_array[i].name = strdup( buf );
    }
}

get_num_foo() 大约比 get_num_foo_with_complex_name() 大 100-1000 倍。该程序在大多数情况下将 'global_foo_array[].name' 视为只读。

我在这里看到了不可忽略的内存节省,我想知道实现这种节省的最佳方法是什么,平衡人力投资。

4

1 回答 1

0

如果您实际上并不需要所有字符串,显而易见的选择是按需创建它们:

struct FOO {
    char *name;
    ...
};

static FOO* global_foo_array; /* NOT in .h file */

void setup_foo(void) {
    int i;
    global_foo_array = (FOO*) malloc ( get_num_foo() * sizeof(FOO) );
    memset(global_foo_array, 0, get_num_foo() * sizeof(FOO) );
}

FOO *get_foo(int i) {
    if (i < 0 || i > get_num_foo())
        return 0;
    if (!global_foo_array[i].name) {
        if (i < get_num_foo_with_complex_name()) {
            global_foo_array.name[i] = malloc ( ... );
        } else {
            char buf[32];
            sprintf( buf, "foo #%d", i );
            global_foo_array[i].name = strdup( buf );
        }
    }
    return &global_foo_array[i];
}

FOO这仍然会为您不需要的所有对象浪费空间。如果它们很大,最好有static FOO **global_foo_array(额外的间接级别),并按需分配它们。

于 2013-05-04T18:01:22.610 回答