C 中的通用数据类型

您好我正在尝试使用void *作为C中的通用数据类型。我想要的是一种机制,使用它我可以存储任何东西并得到任何东西。 我写了一些代码,但在最后一种情况下失败了。 任何人都可以看看代码,如果您有任何其他想法,请告诉我。

我知道我想要存储什么,所以在那一点上我知道数据类型,但在重审期间我只知道起始地址和大小。

这是代码:

#include  #include  #include  #include  static void store( void *destination, void *source, size_t size ) { memcpy ( (char*)destination, source, size); } static void retrieve ( void *destination, void *source, size_t size) { memcpy ( destination, (char*)source, size); } void *storage_char_ptr = (void*) malloc ( sizeof( char* )); void *storage_int_ptr = (void*) malloc ( sizeof(int*)); void *storage_int = (void*) malloc ( sizeof( int)); int main() { int int_in = 65; void *int_out_ptr; int *ptr = ( int*) malloc ( sizeof(int)); memcpy ( ptr, &int_in, sizeof(int)); store ( storage_int_ptr, &ptr, sizeof(int*)); retrieve ( &int_out_ptr, storage_int_ptr, sizeof(int*)); assert ( int_in == *(int*)int_out_ptr); char *char_in = "HelloWorld!!"; void *char_out; store ( storage_char_ptr, &char_in, sizeof(char*)); retrieve ( &char_out, storage_char_ptr, sizeof(char*)); assert ( strcmp ( char_in, (char*)char_out ) == 0 ); char_in = _strdup("HelloWorld!!"); store ( storage_char_ptr, &char_in, sizeof(char*)); retrieve ( &char_out, storage_char_ptr, sizeof(char*)); assert ( strcmp ( char_in, (char*)char_out ) == 0 ); /* This is where it is failing */ int_in = 55; void* int_out; store ( storage_int, &int_in, sizeof(int)); retrieve ( &int_out, storage_int, sizeof(int)); assert ( 55 == *(int*)int_out); } 

最好使用所需类型的联合而不是void* ,并结合所选类型的枚举。 如果您没有有限的类型列表,那么使用包含void*指针的结构和至少分配的大小。

例如:

 struct ANYTYPE { enum { typUndefined, typInt, // 1 typUint, typString, typByteString, typLong, // 5 typFloat, typDouble, } iType; void* value; }; 

这使您可以轻松地正确释放内存,并生成可在分析值之前分析类型的通用代码。 你对union有类似的选择:

 struct ANYTYPE { enum { typUndefined, typInt, // 1 typUint, typString, typLong } iType; union { int i; unsigned int u; char* s; long l; } value; } 

在联合中,所有元素都使用相同的内存空间,只能访问一个。 通过枚举,您知道应该访问哪个元素。 当然,您没有C ++中的OO保护,因此您需要确保在使用此结构的任何位置正确设置枚举。

您正在将整数值(55)复制到指针int_out 。 无论位于(地址下一个4到8个字节)地址55,它都不可能具有数值55.相反,请尝试

 int int_in = 55; int int_out; store ( storage_int, &int_in, sizeof(int)); retrieve ( &int_out, storage_int, sizeof(int)); assert ( 55 == int_out); 

您的代码的另一个问题:在char_in / char_out部分中,您只是复制指针值。 这有效(在这种情况下),但不太可能是你真正想要的,或者是它? 如果您确实想存储指针,可以跳过storeretrieve部分:

 char* str_in = "hello, world"; // Original value void* generic_ptr = str_in; // ... a pointer to which is stored in some data structure char* str_out = generic_ptr; // ... which can later be retrieved 

也会奏效。 另一方面:如果您打算存储字符串的实际内容,则必须复制它(例如,使用_strdup如第二个示例中所示),并将指针保存到字符串的副本

 char* str_in = _strdup("copy me"); void* generic_ptr = str_in; // Gets stored in your data structures 

你正在覆盖指针,然后取消引用它…如果你的代码看起来像这样就可以了……但这可能不是你所追求的。

  int int_out; store ( storage_int, &int_in, sizeof(int)); retrive ( &int_out, storage_int, sizeof(int)); assert ( 55 == int_out); 

要么:

  int *int_out; store ( storage_int, &int_in, sizeof(int)); retrive ( &int_out, storage_int, sizeof(int)); assert ( 55 == (int)int_out); 

但是,在第二种情况下,这有点可疑,因为它假设’int’和’int *’都是相同的大小,所以你可以在检索时将一个存储在另一个之上。 我相信并非所有系统都是如此。

德克是完全正确的。 另一种表达方式是,没有分配空间来放入检索到的数据。

尝试:

 int_in = 55; void* int_out = malloc (sizeof (int_in)); store ( storage_int, &int_in, sizeof(int)); retrieve ( int_out, storage_int, sizeof(int)); assert ( 55 == *(int*)int_out); 

当然,你可能想要使用malloc()以外的东西,并且没有检查malloc()是否失败,但这应该让你走上正确的轨道。