C [void*]中的通用数据类型

Avi*_*ash 10 c

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

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

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>


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);

} 
Run Code Online (Sandbox Code Playgroud)

Ben*_*ery 10

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

例如:

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

    void* value;
};
Run Code Online (Sandbox Code Playgroud)

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

struct ANYTYPE
{
    enum {
      typUndefined,
      typInt,           // 1
      typUint,
      typString,
      typLong
    } iType;

    union
    {
        int i;
        unsigned int u;
        char* s;
        long l;
    } value;
}
Run Code Online (Sandbox Code Playgroud)

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


Dir*_*irk 5

您正在将整数值(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);
Run Code Online (Sandbox Code Playgroud)

你的代码的另一个问题:在char_in/ char_outparts中,你只是复制指针值.这有效(在这种情况下),但不太可能是你真正想要的,或者是它?如果你真的想存储指针,你可以跳过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
Run Code Online (Sandbox Code Playgroud)

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

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