如何取消结构的索引

How do you unindex a struct?

本文关键字:结构 索引 取消 何取消      更新时间:2023-10-16

如何取消结构索引?例:

typedef struct String_s {
    int current_location;
    int size;
    char data[0];
} String;
char* String_getCString(String *str){
    return &str->data[0];
}
//this is supposed to take the result of 'String_getCString' and reverse the process to get the String*
//i.e. String_getCString(CString_getString(str)) == str
String* CString_getString(char *str){ 
    //???
}
int foo(char *cstr){
    printf("%sn", cstr);
    fflush(0);
    free(CString_getString(cstr));
}
int main(int argc, char *argv[]){
    const char *hello_world = "hello world";
    String *str = (String*)malloc(sizeof(String)+1000*sizeof(char));
    str->size = 1000;
    str->count = strlen(hello_world);
    char *cstr = String_getCString(str);
    strcpy(cstr, hello_world);
    foo(cstr);
    return 0;
}

我不是 100% 确定我理解您希望CString_getString做什么,但如果您希望它在传递嵌入式data字段的地址时返回整个String对象的地址,那么这很简单,但很危险:

#include <stddef.h>
String *CString_getString(char *str)
{
    return (String *)(str - offsetof(String, data));
}

如果您希望"取消索引"的字段类型不是[signed/unsigned/] char,则需要在减法之前将输入指针强制转换为char *,并在之后强制转换为所需的返回类型。

这很危险,因为CString_getString无法知道您是否传入了确实String对象的嵌入data字段的str。 如果你弄错了,C 编译器会坐下来,看着它在运行时爆炸。 但是,可以说,这并不比人们一直在 C 中所做的任何其他事情差,这可能是一种有用的技术。 例如,它在Linux的内脏中被大量使用:http://lxr.free-electrons.com/ident?i=container_of