2015-10-06 93 views
1

我在C++中相当新,并且试图理解内存操作是如何工作的。我习惯于Java和Python,并没有真正接触过这个。如何从内存缓冲区中读取C++

我正在研究具有以下结构的项目,这对我来说并不合适。

typedef struct 
{ 
    size_t size; 
    char *data; 
} data_buffer; 

该结构基本上充当缓冲器,具有指针存储在所述缓冲器和所述缓冲器的大小内的数据,以允许程序知道如何大的缓冲液是从它读出时。

的程序如何使用缓存的例子:

data_buffer buffer = {0}; 
//Manipulate data here so it contains pertinent information 
CFile oFile; 
oFile.Write(buffer.data, buffer.size); 

程序大多采用第三方代码读取缓存中找到的数据,所以我无法找到的如何做到这一点的例子。我的主要问题是如何只读取指向字符和大小的指针,如何读取缓冲区的内容?但是,我也想了解这实际上是如何工作的。根据我的理解,内存被写入,并且有一个指向开始位置和内存大小的指针,所以我应该能够遍历内存位置,从内存中抓取每个字符并将其标记到我选择的任何结构上使用,就像一个CString或一个字符串。但是,我不明白如何遍历内存。有人能帮助我更好地理解这一点吗?谢谢。

+0

使用'std :: vector'或'std :: array'而不是裸数组,指针,'new'和'delete'。 –

+0

我正在研究很老的代码,所以很多已经写好的东西我都不能重做。我只是想了解这实际上是如何起缓冲作用的。 – fudge22it

+1

它不是一个缓冲区,它是一个缓冲区句柄,用于确定实际缓冲区的地址和大小。顺便说一句。这是比C++代码更多的C代码(实际上是C代码和MFC代码的混合) – MikeMB

回答

2

没有理由不能使用std :: string或CString来操作这些数据。 (使用更高级别的结构时,提供给你他们。)

获取数据到的std :: string,使用构造函数或赋值操作符:

std::string s(buffer.data, buffer.size); 

你甚至可以把它贴在一个std :: stringstream的,所以你可以把数据缓冲区像一个文件:

std::istringstream ss(s); 

int n; 
ss >> n; 

事情的工作同样的MFC字符串类。

从字符串获取数据,您需要复制它。理想情况下,您可以分配数据的内存。假设你已经写入一个字符串流

std::ostringstream ss; 
ss << name << "," << employee_number; 

然后,您可以分配您需要使用创建的data_buffer对象的函数的空间数据:

function_that_creates_a_data_buffer(buffer, ss.str().size()); 

如果没有这样的功能(就必须有!),你必须的malloc()或新的它自己酌情:

buffer.size = ss.str().size(); 
buffer.data = (char*)malloc(buffer.size); 

现在只是复制:

ss.str().copy(buffer.data, buffer.size); 

如果你的缓冲区需要一个空终止符(我迄今认为它没有),确保给你分配的大小加1,并设置最后一个字符为零。

buffer.size = ss.str().size + 1; 
buffer.data = new char[ buffer.size ]; 
ss.str().copy(buffer.data, buffer.size); 
buffer.data[ buffer.size-1 ] = 0; 

确保查看您将使用的各个类的文档。

希望这会有所帮助。

0

它们使用的是一个char数组,因此您可以访问数据缓冲区的每个字节,因为char的大小通常是1个字节。

读取数据缓冲区的内容取决于应用程序。如果你知道内部数据是如何编码的,你可以编写一个解压函数来选择字符数组的块并将它转换/转换为目标变量。

例如:可以说数据缓冲区实际上是一个大小为4字节的整数列表。

#include <stdio.h> 
#include <stdlib.h> 
int main (int argc, char const* argv[]) 
{ 
    //how the data buffer was probably filled 
    int *a = (int *)malloc(10*sizeof(int)); 
    int i; 
    for(i=0;i<10;i++) { 
    a[i] = i; 
    } 
    char *data = (char *)a; 

    //how we could read from the data buffer 
    int *b = (int *)malloc(10*sizeof(int)); 
    char *p = data; 
    for(i=0;i<10;i++) { 
    b[i]=(int)*p; 
    printf("got value %d\n",b[i]); 
    p += sizeof(int); 
    } 
    free(a); 
    free(b); 
    return 0; 
} 

注:话虽这么说,因为这是C++,这将是更安全的,如果我们能够避免使用char指针与stringsvectors工作。其他答案探讨了如何在C++中正确处理这些缓冲区的其他选项。

0

char *类型的变量实际上是指向内存的指针。你的结构体包含char *类型的数据,所以它是一个指向内存的指针。 (我建议编写char *数据而不是char *数据,以保持清晰。)

因此,您可以使用它作为查看数据的起点。您可以使用另一个指针来遍历缓冲区。

char* bufferInspectorPointer; 
bufferInspectorPointer = buffer.data; 

bufferInspectorPointer现在将指向缓冲区的数据的第一个字节和

*bufferInsepectorPointer 

将返回字节的内容。

bufferInspectorPointer++ 

将指针指向缓冲区中的下一个字节。

你可以做算术与C++指针,所以

bufferInspectorPointer - buffer.data 

会告诉你,你有多少个字节覆盖。你可以将它与buffer.size进行比较,看看你还有多远。

0

既然你把它标记为C++,我推荐使用算法。您可以通过使用buffer.data作为开始,buffer.data + buffer.size作为结束来获得您的iterators。所以对内存复制到std::string你会做一些事情,像这样:

std::string str(buffer.data, buffer.data + buffer.size); 

或许追加到字符串:

str.reserve(str.size() + buffer.size); 
std::copy(buffer.data, buffer.data + buffer.size, std::back_inserter(str)); 

当然,你可以随时选择不同的终点,只要这不是过去buffer.data + buffer.size