Deleting memory allocated by repeated fields - c++

I currently have something like this in my proto file:
message MsgA
{
required string symbol = 1 ;
optional int32 freq = 2 [default = 0];
}
message MsgB
{
repeated MsgA val = 1 ;
}
Now I know that in order to use the repeated field in MsgB. I need to do something like this:
MsgB inst;
MsgA some_val = Get_MsgA_Result();
MsgA* res = inst.add_val();
*res = some_val;
Now my question is once we are done with MsgB how do we reclaim the memory allocated by inst.add_val(); ?

Related

A problem in saving "long double" variables to hdf5 file

I'm new to hdf5. I'm trying to save the results of a simulation in hdf5 file. The variables are long double. So, I mapped them into NATIVE_LDOUBLE. However, the saved values are completely wrong (fluctuating between very small and very large values).
When I save them with NATIVE_DOUBLE, everything is ok. But I need to save long double.
My question is how to properly save long double variables, and moreover quadruple precision variables?
I deeply appreciate your help. Examples are also appreciated.
here is the code
void createHDF5_2DProjectionFile(char* file_name,
CarGrid1D3V<long double>& ph_grid,
std::string first_dim,
std::string second_dim,
long double *x1, int size_x1,
long double *x2, int size_x2)
{
try
{
/* define the size of the datasets containing the coordinates x1
and x2
*/
PredType h5Int = PredType::NATIVE_INT;
PredType h5DoubleL = PredType::NATIVE_LDOUBLE;
PredType h5Double = PredType::NATIVE_DOUBLE;
/* Define the parameters of grid space
DS --> Data Space
*/
hsize_t x1_dims[1], x2_dims[1];
x1_dims[0] = size_x1;
x2_dims[0] = size_x2;
H5File *file_id = new H5File(file_name, H5F_ACC_TRUNC);
/* Saving string attribute
Create dataspace with H5S_SCALAR
Create string datatype of specific length of characters
Create attribute and write to it
*/
DataSpace attr_stringDS = DataSpace(H5S_SCALAR);
StrType strdatatype(PredType::C_S1, 64);
Attribute original_DistFun = file_id->createAttribute("/OriginalDistFun",
strdatatype, attr_stringDS);
original_DistFun.write(strdatatype, "1D3V");
Attribute projection = file_id->createAttribute("/Projection",
strdatatype, attr_stringDS);
projection.write(strdatatype, first_dim + " - " + second_dim);
/* Create the data spaces for grid points along each direction */
DataSpace* first_dimDS_id = new DataSpace(1, x1_dims, NULL);
DataSpace* second_dimDS_id = new DataSpace(1, x2_dims, NULL);
/* Create and fille the datasets for grid points along each direction */
DataSet *data_dim1 = new DataSet(file_id->createDataSet(first_dim,
h5DoubleL, *first_dimDS_id));
data_dim1->write(x1, h5DoubleL);
DataSet *data_dim2 = new DataSet(file_id->createDataSet(second_dim,
h5DoubleL, *second_dimDS_id));
data_dim2->write(x2, h5DoubleL);
/* Important attributes added to the file */
long double x_minmax[2], px_minmax[2],
py_minmax[2], pz_minmax[2], mom_steps[3],
ph_vols[3], spatial_steps[1];
x_minmax[0] = ph_grid.x_min_;
x_minmax[1] = ph_grid.x_max_;
px_minmax[0] = ph_grid.px_min_;
px_minmax[1] = ph_grid.px_max_;
py_minmax[0] = ph_grid.py_min_;
py_minmax[1] = ph_grid.py_max_;
pz_minmax[0] = ph_grid.pz_min_;
pz_minmax[1] = ph_grid.pz_max_;
mom_steps[0] = ph_grid.dpx_;
mom_steps[1] = ph_grid.dpy_;
mom_steps[2] = ph_grid.dpz_;
ph_vols[0] = ph_grid.dvs_;
ph_vols[1] = ph_grid.dvp_;
ph_vols[2] = ph_grid.dv_;
spatial_steps[0] = ph_grid.dx_;
ph_grid.print_characteristics();
std::cout << x_minmax[0] << " , " << x_minmax[1] << "\n";
/* define attributes configuration */
hsize_t space_1[1];
space_1[0] = 1;
hsize_t space_2[1];
space_2[0] = 2;
hsize_t space_3[1];
space_3[0] = 3;
DataSpace attr_space_1 = DataSpace(1, space_1);
DataSpace attr_space_2 = DataSpace(1, space_2);
DataSpace attr_space_3 = DataSpace(1, space_3);
Attribute x_interval = file_id->createAttribute("[x_min,x_max]",
h5DoubleL, attr_space_2);
x_interval.write(h5DoubleL, x_minmax);
Attribute px_interval = file_id->createAttribute("[px_min,px_max]",
h5DoubleL, attr_space_2);
px_interval.write(h5DoubleL, px_minmax);
Attribute py_interval = file_id->createAttribute("[py_min,py_max]",
h5DoubleL, attr_space_2);
py_interval.write(h5DoubleL, py_minmax);
Attribute pz_interval = file_id->createAttribute("[pz_min,pz_max]",
h5DoubleL, attr_space_2);
pz_interval.write(h5DoubleL, pz_minmax);
Attribute MomVolumes = file_id->createAttribute("[dpx,dpy,dpz]",
h5DoubleL, attr_space_3);
MomVolumes.write(h5DoubleL, mom_steps);
Attribute PhVolumes = file_id->createAttribute("[dv_s, dv_m, dv_t]",
h5DoubleL, attr_space_3);
PhVolumes.write(h5DoubleL, ph_vols);
Attribute SpatialVolumes = file_id->createAttribute("[dx]", PredType::NATIVE_DOUBLE,
attr_space_1);
SpatialVolumes.write(h5DoubleL, spatial_steps);
/* Free memory */
delete data_dim1;
delete data_dim2;
delete first_dimDS_id;
delete second_dimDS_id;
delete file_id;
}
catch(DataSetIException error)
{
error.printErrorStack();
}
catch(DataSpaceIException error)
{
error.printErrorStack();
}
catch(FileIException error)
{
error.printErrorStack();
}
}
Update
A great discussion and explanations are available on HDF5 forum where I posted the same question
https://forum.hdfgroup.org/t/a-problem-when-saving-native-ldouble-variables/9504
Also, Steven Varga provided examples to answer this question on his GitHub by constructing a user-defined datatype (see this link).

C++ double free or corruption (out)

Here is my code:
#include "Accounts.h"
using namespace Vibranium;
void Accounts::LoadTable(RowResult &res) {
std::vector<AccountsStruct> accounts;
AccountsStruct accountsStruct;
for (Row row : res.fetchAll()){
accountsStruct.id = row[0].get<int>();
accountsStruct.email = row[1].get<std::string>();
accountsStruct.warTag = row[2].get<std::string>();
accountsStruct.state = row[4].get<int>();
accountsStruct.name = row[5].get<std::string>();
accountsStruct.lastname = row[6].get<std::string>();
accountsStruct.country = row[7].get<std::string>();
accountsStruct.dob_month = row[8].get<int>();
accountsStruct.dob_day = row[9].get<int>();
accountsStruct.dob_year = row[10].get<int>();
accountsStruct.balance = row[11].get<double>();
accountsStruct.created_at = row[12].get<std::string>();
accountsStruct.updated_at = row[13].get<std::string>();
accountsStruct.account_role = row[15].get<int>();
accountsStruct.rank = row[16].get<int>();
accountsStruct.playerRole = row[17].get<int>();
Data.emplace_back(&accountsStruct);
}
std::cout << "SIZE: " << Data.size() << std::endl;
}
Data is std::vector<std::unique_ptr<DataStruct>> Data;.
To add into the vector I call Data.emplace_back(&accountsStruct); which leads me to the following output:
SIZE: 2
double free or corruption (out)
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
I am sure this line Data.emplace_back(&accountsStruct); is causing the issue. Why? How can I fix it?
You're trying to free memory not allocated with new (stack memory, to be precise).
std::vector<std::unique_ptr<DataStruct>> Data;
AccountsStruct accountsStruct; // <-- a stack variable
Data.emplace_back(&accountsStruct); // <-- an instance of unique_ptr is created using the address of accountsStruct
So when Data is destroyed, unique_ptr calls delete on that pointer (not good!!).
I can think of 2 possible solutions:
Allocate accountsStruct on the heap using std::make_unique:
for (auto& row : res.fetchAll()) {
Data.emplace_back(std::make_unique<AccountsStruct>()); // allocate a new instance on the heap
AccountsStruct& accountsStruct = *Data.back(); // get a reference to that instance
accountsStruct.id = row[0].get<int>(); // fill it normally ...
accountsStruct.email = row[1].get<std::string>();
accountsStruct.warTag = row[2].get<std::string>();
. . .
Simplify Data to store by-value: std::vector<DataStruct> Data;
for (auto& row : res.fetchAll()) {
Data.emplace_back(); // allocates a new instance of AccountsStruct in-place
AccountsStruct& accountsStruct = Data.back(); // get a reference to that instance
accountsStruct.id = row[0].get<int>(); // fill it normally ...
accountsStruct.email = row[1].get<std::string>();
accountsStruct.warTag = row[2].get<std::string>();
. . .
Data should contain a std::unique_ptr<AccountsStruct>. I'm afraid, unique_ptr can't be created from AccountsStruct.
So, create struct dynamically, fills by data, create unique_ptr from pointer and add it to vector.
The problem in your code is that you provide an address of a local variable to the constructor of std::unique_ptr.
I assume that Data is std::vector<std::unique_ptr<AccountsStruct>> If AccountsStruct has constructor with no arguments, you can try this:
#include "Accounts.h"
using namespace Vibranium;
void Accounts::LoadTable(RowResult &res) {
std::vector<AccountsStruct> accounts;
// create an instance in the vector and get a reference to it
// auto will be std::unique_ptr<AccountsStruct>&;
auto &accountsStruct = Data.emplace_back();
// work with that reference
for (Row row : res.fetchAll()){
accountsStruct->id = row[0].get<int>();
accountsStruct->email = row[1].get<std::string>();
accountsStruct->warTag = row[2].get<std::string>();
accountsStruct->state = row[4].get<int>();
accountsStruct->name = row[5].get<std::string>();
accountsStruct->lastname = row[6].get<std::string>();
accountsStruct->country = row[7].get<std::string>();
accountsStruct->dob_month = row[8].get<int>();
accountsStruct->dob_day = row[9].get<int>();
accountsStruct->dob_year = row[10].get<int>();
accountsStruct->balance = row[11].get<double>();
accountsStruct->created_at = row[12].get<std::string>();
accountsStruct->updated_at = row[13].get<std::string>();
accountsStruct->account_role = row[15].get<int>();
accountsStruct->rank = row[16].get<int>();
accountsStruct->playerRole = row[17].get<int>();
}
std::cout << "SIZE: " << Data.size() << std::endl;
}
If AccountsStruct is derived from DataStruct you can use:
data.emplace_back(std::make_unique<AccountData>());

Appens to array object

I was playing around with d and i stuck in CaStore class, it accepts the user1 but not the user2 data, i get core.exception.RangeError#main.d(60): Range violation, for example to add db.ccuser[0] = user1; without the [0] and next the db.ccuser[0] = user2; without the [0]
import std.stdio;
class CAdata{ string username;}
class Users{
int age;
CAdata[] info;
this(){
setNull();
}
void setNull(){
age = 0;
info ~= new CAdata();
}
}
class CaStore{
Users[] ccuser;
this(){
ccuser ~= new Users();
}
}
void main()
{
Users user1 = new Users();
user1.age = 24;
user1.info[0].username = "bob";
Users user2 = new Users();
user2.age = 24;
user2.info[0].username = "alice";
CaStore db = new CaStore();
db.ccuser[0] = user1;
db.ccuser[1] = user2;
}
You are writing to a position in the array that is out of bounds.
When you declare your array
Users[] ccuser;
its length is initially 0, there is no room for any elements. Then you append one element, yielding a length of 1:
ccuser ~= new Users();
This is why the first line
db.ccuser[0] = user1;
works but the second one gives you an error:
db.ccuser[1] = user2;
You are writing to index 1, but that is past the end of the array.
You can either:
Append to the array instead:
db.ccuser ~= user2;
Or increase the length of the array to make room:
db.ccuser.length = 2;
db.ccuser[1] = user2; // now there is room for two elements, no error

using std::map<int , std::string> with Google Protocol Buffer

I wanted to know if it was possible to use a map with a google protocol buffer.
I currently have something like this in my .proto file
message MsgA
{
required string symbol = 1 ;
optional int32 freq = 2 [default = 0];
}
message MsgB
{
//What should I do to make a map<int,MsgA>
}
My question is in MsgB i would like to create a type that would be a map::
Any suggestion on how I could accomplish this ?
Do this:
message MapEntry
{
required int32 mapKey = 1;
required MsgA mapValue = 2;
}
message MsgB
{
repeated MapEntry = 1;
}
You will have to write your own code to convert the map to and from a MsgB, but that should be basically trivial.

Function has corrupt return value

I have a situation in Visual C++ 2008 that I have not seen before. I have a class with 4 STL objects (list and vector to be precise) and integers.
It has a method:
inline int id() { return m_id; }
The return value from this method is corrupt, and I have no idea why.
debugger screenshot http://img687.imageshack.us/img687/6728/returnvalue.png
I'd like to believe its a stack smash, but as far as I know, I have no buffer over-runs or allocation issues.
Some more observations
Here's something that puts me off. The debugger prints right values in the place mentioned // wrong ID.
m_header = new DnsHeader();
assert(_CrtCheckMemory());
if (m_header->init(bytes, size))
{
eprintf("0The header ID is %d\n", m_header->id()); // wrong ID!!!
inside m_header->init()
m_qdcount = ntohs(h->qdcount);
m_ancount = ntohs(h->ancount);
m_nscount = ntohs(h->nscount);
m_arcount = ntohs(h->arcount);
eprintf("The details are %d,%d,%d,%d\n", m_qdcount, m_ancount, m_nscount, m_arcount);
// copy the flags
// this doesn't work with a bitfield struct :(
// memcpy(&m_flags, bytes + 2, sizeof(m_flags));
//unpack_flags(bytes + 2); //TODO
m_init = true;
}
eprintf("Assigning an id of %d\n", m_id); // Correct ID.
return
m_header->id() is an inline function in the header file
inline int id() { return m_id; }
I don't really know how best to post the code snippets I have , but here's my best shot at it. Please do let me know if they are insufficient:
Class DnsHeader has an object m_header inside DnsPacket.
Main body:
DnsPacket *p ;
p = new DnsPacket(r);
assert (_CrtCheckMemory());
p->add_bytes(buf, r); // add bytes to a vector m_bytes inside DnsPacket
if (p->parse())
{
read_packet(sin, *p);
}
p->parse:
size_t size = m_bytes.size(); // m_bytes is a vector
unsigned char *bytes = new u_char[m_bytes.size()];
copy(m_bytes.begin(), m_bytes.end(), bytes);
m_header = new DnsHeader();
eprintf("m_header allocated at %x\n", m_header);
assert(_CrtCheckMemory());
if (m_header->init(bytes, size)) // just set the ID and a bunch of other ints here.
{
size_t pos = DnsHeader::SIZE; // const int
if (pos != size)
; // XXX perhaps generate a warning about extraneous data?
if (ok)
m_parsed = true;
}
else
{
m_parsed = false;
}
if (!ok) {
m_parsed = false;
}
return m_parsed;
}
read_packet:
DnsHeader& h = p.header();
eprintf("The header ID is %d\n", h.id()); // ID is wrong here
...
DnsHeader constructor:
m_id = -1;
m_qdcount = m_ancount = m_nscount = m_arcount = 0;
memset(&m_flags, 0, sizeof(m_flags)); // m_flags is a struct
m_flags.rd = 1;
p.header():
return *m_header;
m_header->init: (u_char* bytes, int size)
header_fmt *h = (header_fmt *)bytes;
m_id = ntohs(h->id);
eprintf("Assigning an id of %d/%d\n", ntohs(h->id), m_id); // ID is correct here
m_qdcount = ntohs(h->qdcount);
m_ancount = ntohs(h->ancount);
m_nscount = ntohs(h->nscount);
m_arcount = ntohs(h->arcount);
You seem to be using a pointer to an invalid class somehow. The return value shown is the value that VS usually uses to initialize memory with:
2^32 - 842150451 = 0xCDCDCDCD
You probably have not initialized the class that this function is a member of.
Without seeing more of the code in context.. it might be that the m_id is out of the scope you expect it to be in.
Reinstalled VC++. That fixed everything.
Thank you for your time and support everybody! :) Appreciate it!