如何取消索引结构?例如:
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("%s\n", 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;
}
答案 0 :(得分:3)
我不是100%确定我理解您希望CString_getString
做什么,但是如果您希望它在传递嵌入式{String
地址时返回整个data
对象的地址1}}字段,然后那是直截了当的,但很危险:
#include <stddef.h>
String *CString_getString(char *str)
{
return (String *)(str - offsetof(String, data));
}
如果您希望“取消索引”的字段类型不是[signed/unsigned/] char
,则需要在减法之前将输入指针强制转换为char *
,以及转换为所需的字段之后返回类型。
这很危险,因为CString_getString
无法知道您是否已传入str
确实是 data
字段{ {1}}对象。如果你弄错了,C编译器就会退后一步,在运行时监视它。但是,可以说,这并不比C中所做的任何事情都要糟糕,而且可以是一种有用的技术。例如,它在Linux的内容中被大量使用:http://lxr.free-electrons.com/ident?i=container_of