Search code examples
c++structbus-error

Store more data in iov in C++


I am writing a C++ program (see below). My goal is to store data in iov struct. I have allocated buffer of fixed length in constructor. Every time that buffer gets filled, I want to transfer data in iov and allocated new buffer of fixed length. Finally when done with data processing, I want to return iov struct. My intension here is to store all these data into iov so that if it's required in future, I can send data easily. I have written sample code. But it seems it's not working. I got an "Bus error: 10". Can someone help me?

Sample code:

#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;
}

Solution

  • Without understanding the intent of your program in detail, it is very clear that you forgot to reserve memory for the iov-objects themselfes. For example, in your constructor you write iov[0].iov_base = buf, yet iov has not been allocated before.

    To overcome this, somewhere in your code, before the first access to iov, you should write something like iov = calloc(100,sizeof(struct iovev)) or a c++ equivalent using new[].

    Consider the following program:

    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
    }