你如何从内存缓冲区中读取 C++
How do you read from a memory buffer c++
我是 C++ 的新手,正在尝试了解内存操作的工作原理。我习惯了 Java 和 Python 并没有真正接触过这个。
我正在从事的项目具有以下结构,但我不太理解。
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);
该程序主要使用第 3 方代码来读取在缓冲区中找到的数据,因此我很难找到如何完成此操作的示例。我的主要问题是 如何读取缓冲区的内容,仅给出一个指向字符和大小的指针? 但是,我也想了解这实际上是如何工作的。据我所知,内存被写入,并带有指向其开始位置和内存大小的指针,因此我应该能够遍历内存位置,从内存中获取每个字符并将其标记到我选择的任何结构上使用,如 CString 或字符串。然而,我不明白如何遍历内存。有人可以帮助我更好地理解这一点吗?谢谢
他们正在使用 char
数组,因此您可以访问数据缓冲区的每个字节,因为 char
的大小通常为 1 个字节。
读取数据缓冲区的内容取决于应用程序。如果您知道内部数据是如何编码的,您可以编写一个解包函数,它选择 char 数组的块并将其 convert/typecast 到目标变量。
例如:假设数据缓冲区实际上是一个 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
指针并使用 strings
或 vectors
会更安全。其他答案探讨了如何在 C++ 中正确处理此类缓冲区的其他选项。
char*类型的变量实际上是一个指向内存的指针。您的结构包含类型为 char* 的数据,因此它是指向内存的指针。 (我建议写 char* 数据而不是 char *data,以帮助保持清晰。)
因此您可以将其用作查看数据的起点。您可以使用另一个指针遍历缓冲区。
char* bufferInspectorPointer;
bufferInspectorPointer = buffer.data;
bufferInspectorPointer 现在将指向缓冲区数据的第一个字节并且
*bufferInsepectorPointer
将return字节的内容。
bufferInspectorPointer++
会将指针前进到缓冲区中的下一个字节。
你可以在 C++ 中用指针做算术运算,所以
bufferInspectorPointer - buffer.data
会告诉你已经覆盖了多少字节。您可以将它与 buffer.size 进行比较,看看您还剩多少。
既然您将其标记为 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
。
,您总是可以选择不同的结局
没有理由不能使用 std::string 或 CString 来操作该数据。 (在可用时使用更高级别的结构。)
要将数据放入std::string,使用构造函数或赋值运算符:
std::string s( buffer.data, buffer.size );
您甚至可以将其粘贴到 std::string 流中,这样您就可以像对待文件一样对待数据缓冲区:
std::istringstream ss( s );
int n;
ss >> n;
MFC 字符串 class.
的工作方式类似
要从字符串中获取数据,您需要将其复制过来。理想情况下,您将能够分配数据的内存。假设您已将数据写入 stringstream
std::ostringstream ss;
ss << name << "," << employee_number;
然后您可以使用创建 data_buffer 对象的函数分配您需要的 space:
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 );
如果您的缓冲区需要一个空终止符(到目前为止我一直假设它不需要),请确保在您分配的大小上加一并将最后一个字符设置为零。
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;
确保查看您将使用的各种 classes 的文档。
希望对您有所帮助。
我是 C++ 的新手,正在尝试了解内存操作的工作原理。我习惯了 Java 和 Python 并没有真正接触过这个。
我正在从事的项目具有以下结构,但我不太理解。
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);
该程序主要使用第 3 方代码来读取在缓冲区中找到的数据,因此我很难找到如何完成此操作的示例。我的主要问题是 如何读取缓冲区的内容,仅给出一个指向字符和大小的指针? 但是,我也想了解这实际上是如何工作的。据我所知,内存被写入,并带有指向其开始位置和内存大小的指针,因此我应该能够遍历内存位置,从内存中获取每个字符并将其标记到我选择的任何结构上使用,如 CString 或字符串。然而,我不明白如何遍历内存。有人可以帮助我更好地理解这一点吗?谢谢
他们正在使用 char
数组,因此您可以访问数据缓冲区的每个字节,因为 char
的大小通常为 1 个字节。
读取数据缓冲区的内容取决于应用程序。如果您知道内部数据是如何编码的,您可以编写一个解包函数,它选择 char 数组的块并将其 convert/typecast 到目标变量。
例如:假设数据缓冲区实际上是一个 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
指针并使用 strings
或 vectors
会更安全。其他答案探讨了如何在 C++ 中正确处理此类缓冲区的其他选项。
char*类型的变量实际上是一个指向内存的指针。您的结构包含类型为 char* 的数据,因此它是指向内存的指针。 (我建议写 char* 数据而不是 char *data,以帮助保持清晰。)
因此您可以将其用作查看数据的起点。您可以使用另一个指针遍历缓冲区。
char* bufferInspectorPointer;
bufferInspectorPointer = buffer.data;
bufferInspectorPointer 现在将指向缓冲区数据的第一个字节并且
*bufferInsepectorPointer
将return字节的内容。
bufferInspectorPointer++
会将指针前进到缓冲区中的下一个字节。
你可以在 C++ 中用指针做算术运算,所以
bufferInspectorPointer - buffer.data
会告诉你已经覆盖了多少字节。您可以将它与 buffer.size 进行比较,看看您还剩多少。
既然您将其标记为 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
。
没有理由不能使用 std::string 或 CString 来操作该数据。 (在可用时使用更高级别的结构。)
要将数据放入std::string,使用构造函数或赋值运算符:
std::string s( buffer.data, buffer.size );
您甚至可以将其粘贴到 std::string 流中,这样您就可以像对待文件一样对待数据缓冲区:
std::istringstream ss( s );
int n;
ss >> n;
MFC 字符串 class.
的工作方式类似要从字符串中获取数据,您需要将其复制过来。理想情况下,您将能够分配数据的内存。假设您已将数据写入 stringstream
std::ostringstream ss;
ss << name << "," << employee_number;
然后您可以使用创建 data_buffer 对象的函数分配您需要的 space:
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 );
如果您的缓冲区需要一个空终止符(到目前为止我一直假设它不需要),请确保在您分配的大小上加一并将最后一个字符设置为零。
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;
确保查看您将使用的各种 classes 的文档。
希望对您有所帮助。