0

The table in my database has got one blob type column. I use it to store the following structure:

struct a
{
int x;
string y;
} ;

I've written a C++ function to retrieve this blob using the above mentions structure's variable. I'm using cass_value_get_bytes function for that.

The problem is that I get a segmentation fault if I use the above mentioned structure. However if I change the string type to a character array, the problem solves. I'm unable to understand why can't I use a string variable as it's so much neater to use a string than a character array.

Vishal Sharma
  • 1,670
  • 20
  • 55
  • 7
    You can't store a `string` in binary form for later retrieval, it contains pointers. You need to serialize it. (Or use an array.) – molbdnilo Dec 15 '17 at 13:28
  • 1
    I recommend you look into the subject of [*serialization*](https://en.wikipedia.org/wiki/Serialization). Complex data-structures (and yes `std::string` is one) can't really be stored with a bit- or byte-wise dump of the object itself. – Some programmer dude Dec 15 '17 at 13:32
  • 1
    You are performing a shallow copy of the structure. It means copying the string object, not the data it holds (your string). Your actual string is stored in dynamic memory. Only the pointer is kept in the string instance in the structure. – Fabien Bouleau Dec 15 '17 at 13:38
  • _"However if I change the string type to a character array, the problem solves."_ Yes, because you store the data in the `struct`, not just a pointer to memory elsewhere that only existed on 1 run... As well as serialisation, see [What is the difference between a deep copy and a shallow copy?](https://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy) & more directly [Read/Write struct containing string property to binary file](https://stackoverflow.com/questions/22961017/read-write-struct-containing-string-property-to-binary-file) & many more – underscore_d Dec 15 '17 at 13:38
  • 1
    Possible duplicate of [How to read / write a struct in Binary Files?](https://stackoverflow.com/questions/5506645/how-to-read-write-a-struct-in-binary-files) – underscore_d Dec 15 '17 at 13:47

2 Answers2

2

The functions cass_value_get_string() and cass_value_get_bytes() return a pointer into a buffer whose lifetime is bound to CassResult. When the result is deleted so is the memory of the values. You need to copy the memory into the string's buffer. cass_value_get_string() can also be used for blobs and it avoid having to do a reinterpret_cast<>. You can do something like the following:

#include <cassandra.h>
#include <string>

std::string to_string(CassValue* value) {
  const char* str;
  size_t len;
  cass_value_get_string(value, &str, &len);
  return std::string(str, len);
}

struct SomeData {
  int x;
  std::string y;
};

int main() {
  SomeData data;
  CassValue* value = NULL; /* This needs to be set from the result */
  data.y = to_string(value);
}
mikep
  • 129
  • 4
  • You probably also want to check the result of the functions `cass_value_get_string()` and `cass_value_get_bytes()` for errors, but I left them out for brevity. – mikep Dec 15 '17 at 14:21
  • How can blob(populated by a structure having different types of data members, in my case, an integer and a string) be extracted by using cass_value_get_string()? – Vishal Sharma Dec 15 '17 at 15:18
  • Sorry, I guess I misunderstood what you were originally asking. Could you store the integer and string separately in Cassandra instead of encoding them in a blob? Otherwise, I would need more information about your blob's serialization format to figure out how to help you decode them. – mikep Dec 15 '17 at 15:36
  • That is: `CREATE TABLE test (key varchar PRIMARY KEY, ivalue int, svalue varchar)` instead of `CREATE TABLE test (key varchar PRIMARY KEY, bvalue blob)` – mikep Dec 15 '17 at 15:40
0
 You need to allocate memory dynamically,Watch this Example.

 #include<stdlib.h>
 #include<string.h>
 #include<stdio.h>
struct employee{
int no;
char name[20];
double sal;
 } ;




void main()
{

 struct employee emp={
         1234,"Aravind",20000.0
                     };
       struct employee *e=(struct employee*) malloc( sizeof(struct   employee)*1 );


  strcpy(e->name,"Byju");
  e->sal=20000.0;
  e->no=1265;
  printf("\n %d    \t %s \t %lf",emp.no,emp.name,emp.sal);
  printf("\n %d    \t %s \t %lf",e->no,e->name,e->sal);

   }
   Output:
   1234      Aravind     20000.000000
   1265      Byju        20000.000000