将类对象存储在 char * 缓冲区中并从缓冲区引用该对象

Posted

技术标签:

【中文标题】将类对象存储在 char * 缓冲区中并从缓冲区引用该对象【英文标题】:Storing a class object in a char * buffer and referencing the object from the buffer 【发布时间】:2013-09-04 06:28:08 【问题描述】:

我要做的是将一个类对象放在缓冲区中,然后以后能够正确引用它。本质上它是一个使用缓冲区进行数据存储的容器类。我想到的最好的方法是存储缓冲区中对象的地址,通过其索引引用它,然后对其进行转换。我现在看到这样做可能会导致内存泄漏,因为该对象仅在此方法中本地存在,并且正在返回该本地对象的地址。有没有办法可以将对象存储到缓冲区中,然后通过调用重载的 operator[] Foo[index] 来正确引用它? 我曾尝试对C++: Casting an Object to char* for saving/loading 使用相同的技术,但在我尝试对缓冲区中的内容进行地址查找时,静态/重新解释转换往往会更改地址值。

ps。我知道使用向量将是存储类对象的一种更简单的方法,但部分限制是我不能使用 STL 进行数据存储并且必须依赖给我的缓冲区。

#include <stdlib.h>
#include <assert.h>
#ifndef FOO_H_
#define FOO_H_

template <typename T>
class Foo 
    char * oBuffer = NULL;
    unsigned items = 0, bSize = 0;
public:
    Foo(char * pBuffer, unsigned nBufferSize) :
        oBuffer(pBuffer),
        items(),
        bSize(nBufferSize)

        /*for (unsigned i =0; i < nBufferSize; i++)
            oBuffer[i] = &pBuffer[i];*/
    
    ~Foo() delete[] oBuffer;

    T * Add()              ///======   Adds an element to the container, constructs it and returns it to the caller.
        assert(Capacity() > Count());
        T nObj; // new object
        T *nElement = &nObj; // address of new object
        oBuffer += items;    // incrementing pointer by item count    
            oBuffer = (char*) nElement; // attempt to store object address in buffer[items] location
        items++; // increment items count by one
        return (T*) &oBuffer;
    

    T *  operator [] (unsigned nIndex)         ///======   Returns the n th element of the container [0..Count -1].
        return (T*) (&oBuffer[nIndex]);
    

;

#endif

最初我试图按如下方式添加:

T *  Add()             ///======   Adds an element to the container, constructs it and returns it to the caller.
        assert(Capacity() > Count());
        T *add =&(oBuffer[items++] = T);
        return add;
    

但是当 T = 是自定义类对象时,我会遇到问题。

【问题讨论】:

你在那里尝试做的事情不会奏效。您正在寻找的是序列化。 @g-makulik 在这种情况下你可以举一个序列化的例子吗?我没有做太多的序列化,任何示例都会有所帮助。 这是一个广阔的领域。您可以从 Joachim Pileborg 的回答中的链接开始。 Boost 提供了一个序列化库,s11n 是另一个。除了序列化之外,placement new 可能是您正在寻找的内容,具体取决于您的用例。 【参考方案1】:

您的Add 函数中有未定义的行为,首先您存储一个指向局部变量的指针(使用oBuffer = (char*) nElement),然后使用相同的语句覆盖原始指针,这您已经在上面的语句中覆盖,然后返回指针的地址(即char **),但将其转换为单个指针。

您的索引功能也不起作用,因为nIndexchar“数组”中的索引,除非模板化类型Tchar,否则不会相同。

如果要存储某种类型的对象,请使用std::vector

如果您希望 serialization 保存到文件/通过网络发送,它也不适用于包含指针、集合、文件等的任何类型。

【讨论】:

以上是关于将类对象存储在 char * 缓冲区中并从缓冲区引用该对象的主要内容,如果未能解决你的问题,请参考以下文章

WebGL:读取缓冲区对象的内容?

使用带有 char * 的正则表达式迭代器

我可以将 char* 缓冲区转换为对象类型吗?

如何在 C++ 中序列化结构数据?

将整数复制到缓冲区 memcpy C++

如何在 opencl c 内核上使用 vector<char**> 缓冲区或使用此向量设置 SVM?