在 C++ 中的 iov 中存储更多数据
Store more data in iov in C++
我正在编写 C++ 程序(见下文)。我的目标是将数据存储在 iov 结构中。我在构造函数中分配了固定长度的缓冲区。每次缓冲区被填满时,我都想在 iov 中传输数据并分配新的固定长度的缓冲区。最后完成数据处理后,我想要 return iov 结构。我这里的意图是把这些数据都存到iov里面,以后有需要的时候可以很方便的发送数据。我写了示例代码。但它似乎不起作用。我得到了一个 "Bus error: 10"。有人能帮我吗?
示例代码:
#include <iostream>
#include <string>
#include <sys/uio.h>
#include <cstdlib>
using namespace std;
#define MAX_LEN 1000
#define MIN_LEN 20
class MyClass
{
public:
MyClass();
~MyClass();
void fillData(std::string &data);
private:
struct iovec *iov;
unsigned int count;
unsigned int len;
char *buf;
unsigned int total_len;
unsigned int tmp_len;
};
MyClass::MyClass()
{
cout << "Inside constructor" << endl;
total_len = MIN_LEN;
buf = (char *)malloc(MAX_LEN);
if (buf == NULL) {
cout << "Error: can’t allocate buf" << endl;
exit(EXIT_FAILURE);
}
}
MyClass::~MyClass()
{
free(buf);
}
void MyClass::fillData(std::string &data)
{
unsigned int d_len, tmp_len, offset;
d_len = data.size();
const char* t = data.c_str();
total_len += d_len;
tmp_len += d_len;
if (total_len > MAX_LEN) {
/* Allocate memory and assign to iov */
tmp_len = d_len;
}
memcpy(buf + offset, t, d_len);
/* Adjust offset */
}
int main()
{
MyClass my_obj;
int i;
std::string str = "Hey, welcome to my first class!";
for (i = 0; i < 10; i++) {
my_obj.fillData(str);
}
return 0;
}
在没有详细了解程序意图的情况下,很明显您忘记了为 iov
对象本身保留内存。
例如,在你的构造函数中你写了 iov[0].iov_base = buf
,但是 iov
之前还没有分配。
为了克服这个问题,在您的代码中的某处,在第一次访问 iov
之前,您应该编写类似 iov = calloc(100,sizeof(struct iovev))
的内容或使用 new[]
.[=17= 的 C++ 等价物]
考虑以下程序:
struct myStruct {
char *buf;
int len;
};
int main() {
struct myStruct *myStructPtr;
myStructPtr->buf = "Herbert"; // Illegal, since myStructPtr is not initialized; So even if "Herbert" is valid, there is no place to store the pointer to literal "Herbert".
myStructPtr[0].buf = "Herbert"; // Illegal, since myStructPtr is not initialized
// but:
struct myStruct *myStructObj = new (struct myStruct);
myStructObj->buf = "Herbert"; // OK, because myStructObj can store the pointer to literal "Herbert"
myStructObj->buf = "Something else"; // OK; myStructObj can hold a pointer, so just let it point to a different portion of memory. No need for an extra "new (struct myStruct)" here
}
我拿了你的代码,它没有完全使用 iovec
的任何东西,我稍微修改了一下。
我不确定为什么开发人员更喜欢 char*
而不是 std::string
的缓冲区
或者为什么使用应该分配然后删除的指针而不是使用 std::vector
我还添加了一个使用 iovec 的函数。它被称为void MyClass::print_data()
。它打印向量 iovecs
中的所有数据
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <unistd.h>
#include <sys/uio.h>
using namespace std;
class MyClass
{
vector<struct iovec> iovs;
vector<string> bufs;
public:
MyClass();
~MyClass();
void fill_data(const string &data);
void print_data();
};
MyClass::MyClass()
{
cout << "Inside constructor" << endl;
}
MyClass::~MyClass()
{
}
void MyClass::fill_data(const string &data)
{
stringstream stream;
stream << setw(2) << setfill(' ') << (this->bufs.size() + 1) << ". "
<< data << endl;
this->bufs.push_back(stream.str());
iovec iov = {&(bufs.back()[0]), bufs.back().size()};
this->iovs.push_back(iov);
}
void MyClass::print_data() {
writev(STDOUT_FILENO, iovs.data(), iovs.size());
}
int main() {
MyClass my_obj;
string str = "Hey, welcome to my first class!";
for (int i = 0; i < 10; ++i) {
my_obj.fill_data(str);
}
my_obj.print_data();
return 0;
}
像这样编译它:g++ test.cpp
我正在编写 C++ 程序(见下文)。我的目标是将数据存储在 iov 结构中。我在构造函数中分配了固定长度的缓冲区。每次缓冲区被填满时,我都想在 iov 中传输数据并分配新的固定长度的缓冲区。最后完成数据处理后,我想要 return iov 结构。我这里的意图是把这些数据都存到iov里面,以后有需要的时候可以很方便的发送数据。我写了示例代码。但它似乎不起作用。我得到了一个 "Bus error: 10"。有人能帮我吗?
示例代码:
#include <iostream>
#include <string>
#include <sys/uio.h>
#include <cstdlib>
using namespace std;
#define MAX_LEN 1000
#define MIN_LEN 20
class MyClass
{
public:
MyClass();
~MyClass();
void fillData(std::string &data);
private:
struct iovec *iov;
unsigned int count;
unsigned int len;
char *buf;
unsigned int total_len;
unsigned int tmp_len;
};
MyClass::MyClass()
{
cout << "Inside constructor" << endl;
total_len = MIN_LEN;
buf = (char *)malloc(MAX_LEN);
if (buf == NULL) {
cout << "Error: can’t allocate buf" << endl;
exit(EXIT_FAILURE);
}
}
MyClass::~MyClass()
{
free(buf);
}
void MyClass::fillData(std::string &data)
{
unsigned int d_len, tmp_len, offset;
d_len = data.size();
const char* t = data.c_str();
total_len += d_len;
tmp_len += d_len;
if (total_len > MAX_LEN) {
/* Allocate memory and assign to iov */
tmp_len = d_len;
}
memcpy(buf + offset, t, d_len);
/* Adjust offset */
}
int main()
{
MyClass my_obj;
int i;
std::string str = "Hey, welcome to my first class!";
for (i = 0; i < 10; i++) {
my_obj.fillData(str);
}
return 0;
}
在没有详细了解程序意图的情况下,很明显您忘记了为 iov
对象本身保留内存。
例如,在你的构造函数中你写了 iov[0].iov_base = buf
,但是 iov
之前还没有分配。
为了克服这个问题,在您的代码中的某处,在第一次访问 iov
之前,您应该编写类似 iov = calloc(100,sizeof(struct iovev))
的内容或使用 new[]
.[=17= 的 C++ 等价物]
考虑以下程序:
struct myStruct {
char *buf;
int len;
};
int main() {
struct myStruct *myStructPtr;
myStructPtr->buf = "Herbert"; // Illegal, since myStructPtr is not initialized; So even if "Herbert" is valid, there is no place to store the pointer to literal "Herbert".
myStructPtr[0].buf = "Herbert"; // Illegal, since myStructPtr is not initialized
// but:
struct myStruct *myStructObj = new (struct myStruct);
myStructObj->buf = "Herbert"; // OK, because myStructObj can store the pointer to literal "Herbert"
myStructObj->buf = "Something else"; // OK; myStructObj can hold a pointer, so just let it point to a different portion of memory. No need for an extra "new (struct myStruct)" here
}
我拿了你的代码,它没有完全使用 iovec
的任何东西,我稍微修改了一下。
我不确定为什么开发人员更喜欢 char*
而不是 std::string
的缓冲区
或者为什么使用应该分配然后删除的指针而不是使用 std::vector
我还添加了一个使用 iovec 的函数。它被称为void MyClass::print_data()
。它打印向量 iovecs
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <unistd.h>
#include <sys/uio.h>
using namespace std;
class MyClass
{
vector<struct iovec> iovs;
vector<string> bufs;
public:
MyClass();
~MyClass();
void fill_data(const string &data);
void print_data();
};
MyClass::MyClass()
{
cout << "Inside constructor" << endl;
}
MyClass::~MyClass()
{
}
void MyClass::fill_data(const string &data)
{
stringstream stream;
stream << setw(2) << setfill(' ') << (this->bufs.size() + 1) << ". "
<< data << endl;
this->bufs.push_back(stream.str());
iovec iov = {&(bufs.back()[0]), bufs.back().size()};
this->iovs.push_back(iov);
}
void MyClass::print_data() {
writev(STDOUT_FILENO, iovs.data(), iovs.size());
}
int main() {
MyClass my_obj;
string str = "Hey, welcome to my first class!";
for (int i = 0; i < 10; ++i) {
my_obj.fill_data(str);
}
my_obj.print_data();
return 0;
}
像这样编译它:g++ test.cpp