Reading data into a void* variable in struct - c++

I have a struct SInfoEntry to store data that I read from a VCF file.
struct SInfoEntry
{
int type; //Info Type
std::string key; //Info Tag
void* values = NULL; //Data
int n; //Len
};
In the code below, I am trying to store my data in values variable in my struct. However I am getting error when I am trying to do that:
SInfoEntry infoEntry;
//This line is giving me EXC_BAD_ACCESS exception
bcf_get_info_values(m_pHeader, m_pRecord, "AF", (void**)(&infoEntry.values), &infoEntry.n, BCF_HT_REAL);
However instead if I declare a local array, the function successfully return me the data I want:
void* values = NULL;
int nvalue;
bcf_get_info_values(m_pHeader, m_pRecord, "AF", (void**)(&values), &nvalue, BCF_HT_REAL);
Why is that trying to read data into struct fails? Am I missing something in pointer arithmetic?
I am using 'bcf_get_info_values' function from an external library and here is the signature of the function:
int bcf_get_info_values(const bcf_hdr_t *hdr, bcf1_t *line, const char *tag, void **dst, int *ndst, int type);
Edit: Here is the Link of the source of bcf_get_info_values function. As I can see, I do not need to allocate memory since the function is using realloc().

What you are actually doing is coping data to an unallocated memory space.
In the first example it is probably initialized to NULL, hence the app crashed.
the second example is just coping data to random memory places, this shouldnt work and is extremely dangerous.
you can do one of the following:
Declare an array with size as the maximum object size you want to put in it:
uint8_t values[1000];
int nvalue;
bcf_get_info_values(m_pHeader, m_pRecord, "AF", (void**)(&values), &nvalue, BCF_HT_REAL);
Or allocate the array dynamically:
void* values = malloc(size);
int nvalue;
bcf_get_info_values(m_pHeader, m_pRecord, "AF", (void**)(&values), &nvalue, BCF_HT_REAL);

Related

C++: Store function in byte array, then execute function through function pointer

~ Is it possible to read the bytes of a function, put them into an array, create a function pointer to the beginning address of the array and then execute the function pointer
So obviously there are a lot of things that would need to be done, the best method I have currently for getting the bytes in a function is to create a pointer, and iterate through each memory address until I hit the RET (0xc3) instruction. I've managed to Frankenstein together some code, but no matter what happens I get an access violation, which leads me to my question, is this even possible, is there a procedure that needs to be followed to allow this to happen.
Rough Example:
void function() {
//do something
return;
}
int main() {
size_t size = sizeofFunc(function); //uses method listed earlier
unsigned char* bytes = new unsigned char[size];
// for each memory address from 'function' to 'function + size' put contents into 'bytes'
void(*vFuncPtr)(void) = (void(*)(void))bytes;
vFuncPtr(); // Access Violation, is this even possible???
}
Here is the way to do it :
void function() {
printf("hello\n");
return;
}
int main()
{
char* bytes = new char[4];
bytes = reinterpret_cast<char*>(function);
void(*vFuncPtr)(void) = (void(*)(void))bytes;
vFuncPtr();
return 0;
}

c++ initializing char array member of class

in my c++ project I have class with two members. the char array member I have problems with.
class frame_message
{
public:
explicit frame_message(const unsigned int id, const char data[]) :id_(id), data_{ *data }{};
// only the first char 'a' is copied to `data_`
char* get_data() { return data_; };
void get_data(char** data) { *data = data_; };
private:
unsigned int id_; char data_[8];
};
now from main method I want to send another char array used to initialize the class array.
main
{
char data[8]={'a','b','c'} // indexs 3 to 7 are '\0'
char data2[8];
char data3[8];
frame_message myMessage(0xF004,data); // the data is passed as "abc"
data2 = myMessage.get_data(); // analysis error
myMessage.get_data(&data3); // runtime exception
}
How should I initialize the private member of class with exactly the data array send to constructor?
also for for get_data functions what data type should be passed?
p.s. I am new in c/c++ and yet get confused in pointers, references and specially char and char*
For the constructor, it would be a good idea to pass a length parameter as well because you can accept only up to 8 bytes.
Then, if your length is <= 8 :
memcpy(data_, data, length)
Same thing in your parameterized get_data, so it would be:
memcpy(*data, data_, 8) /* Assuming that they provide long enough array. */
It is good practice when dealing with arrays to always include length, and when dealing with pointers to check if they are NULL - I'll leave this to you.
The reason you were getting errors is because you cannot assign a pointer to a statically declared array - it has a fixed address, you can only change the content.

get length of buffer using lower-level method on stack and heap

Like following code:
#include <iostream>
#include <string>
#define BUF_LEN_HEAP 32
#define BUF_LEN_STACK 64
int getBufLen(const char *buf)
{
//...
}
void foo(const char *buf)
{
int len = getBufLen(buf);
//memcpy(new_buf, buf, len);
//...
}
int main()
{
char buf_stack[BUF_LEN_STACK];
char *buf_heap = new char[BUF_LEN_HEAP];
std::string str("abcdef");
foo(buf_stack);
foo(buf_heap);
foo(str.c_str());
delete [] buf_heap;
return 0;
}
If get length of buffer very difficult pass argument to the functions.
Is there lower-level method to get length of buffer whatever the buffer allocated on stack or heap?
No, there is no way to get the size of an array outside of the method that declared it, and only if the array was declared with a static length (known at compile time).
The usual way to handle this is to pass both a pointer and a size to any function writing to the buffer, just as memcpy does.
With c++ there's always the better option to use a std::vector instead of a plain array. The std::vector carries all needed information within one object that's easy to pass around.

Is it alright to use memcpy() to copy a struct that contains a pointer?

I was thinking about this the other day and I am curious if this is a bad idea...
Lets say there is a structure that contains a pointer to a string array.
Would the memcpy() copy the 'name' array pointer in the below example?
Edit: The std is inaccessible in this example.
struct charMap
{
unsigned char * name;
unsigned char id;
};
typedef struct charMap CharMapT;
class ABC
{
public:
ABC(){}
void Function();
CharMapT* structList;
}
void ABC::Function ()
{
CharMapT list[] =
{
{"NAME1", 1},
{"NAME2", 2},
{"NAME3", 3}
};
structList = new CharMapT[sizeof(list)];
memcpy(structList, &list, sizeof(list));
}
There are several errors in the code presented, which I will talk about first, followed by my stock-diatribe of pointers vs. arrays.
struct charMap
{
unsigned int * name;
unsigned int id;
};
typedef struct charMap CharMapT;
This declares a structure type that includes a pointer to unsigned int as the first member (name) and an int as the second member (id). On a 32-bit system with default byte packing this will be 8 bytes wide (32-bit pointer = 4bytes, 32-bit signed int=4bytes). If this is a 64-bit machine the pointers will be 8 bytes wide, the int still-likely 32-bits wide, making the structure size 12 bytes.
Questionable Code
void ABC::Function ()
{
CharMapT list[] =
{
{"NAME1", 1},
{"NAME2", 2},
{"NAME3", 3}
};
structList = new CharMapT[sizeof(list)];
memcpy(structList, &list, sizeof(list));
}
This allocates dynamic array of CharMapT structs. How many? More than you think. The sizeof(list) will return the byte-count of the list[] array. Since a CharMapT structure is 8 bytes wide (see above) this will 3 * 8, or 24 CharMapT items (36 items if using 64-bit pointers).
We then memcpy() 24 bytes (or 36 bytes) from list (the & in &list is unecessary) to the newly allocated memory. this will copy over 3 CharMapT structures, leaving the other 21 we allocated untouched (beyond their initial default construction).
Note: you're initializing a const char * to a field declared as unsigned int *, so if this even compiled the fundamental data type would be different. Assuming you fixed your structure and change the pointer type to const char *, the addresses of the static string constants (the addresses of the "NAME" constants) somewhere in your const data segment will be assigned to the pointer variables of the elements in structList[0].name, structList[2].name, and structList[3].name respectively.
This will NOT copy the data pointed to. it will only copy the pointer values. If you want copies of the data then you must raw-allocate them (malloc, new, whatever).
Better still, use an std::vector<CharMapT>, use std::string for CharMapT::name, and use std::copy() to replicate the source (or even direct-assignment).
I hope that explains what you were looking for.
Pointer vs. Array Diatribe
Never confuse a pointer with an array. A pointer is a variable that holds an address. Just like an int variable hold an integer value, or a char variable holds a character type, the value held in a pointer is an address
An array is different. It is also a variable (obviously), but it cannot be an l-value, and nearly every place it is typically used a conversion happens. Conceptually that conversion results in a temporary pointer that points to the data type of the array, and holds the address of the first element. There are times when that concept does not happen (such as the applying the address-of operator).
void foo(const char * p)
{
}
char ar[] = "Hello, World!";
foo(ar); // passes 'ar', converted to `char*`, into foo.
// the parameter p in foo will *hold* this address
or this:
char ar[] = "Goodbye, World!";
const char *p = ar; // ok. p now holds the address of first element in ar
++p; // ok. address in `p` changed to address (ar+1)
but not this:
char ar[] = "Goodbye, World!";
++ar; // error. nothing to increment.
It won't copy your actual data pointed by name. It will copy the pointer and you'll have 2 pointers to the same place in 2 objects (for each pair of objects in 2 arrays).
All you really need to know here is that memcpy will give you a bit for bit copy of the original. So what you'll have is two pointers with the same value (i.e., an address) which refer to the same data.
On a side note, you have declared name as a pointer to int, which is of course wrong here. It should be a const char*. Also, as this is C++ and not C, you're better served by something like std::copy which won't break your code subtly if charMap someday becomes a complex type. On the same note, prefer std::string instead of const char* in most situations.
Your use of sizeof() is wrong when calling new. You are allocating an array of CharMapT elements. You have to specify the number of elements, but you are specifying a byte count instead. So you need to fix that:
structList = new CharMapT[sizeof(list) / sizeof(CharMapT)];
With that fixed, the result of the memcpy() will be that structList will contains an exact copy of the raw data that list[] contains. That means that the structList[N].name pointers will contain the same values as the list[N].name pointers, and thus they will all be pointing at the same physical memory for the string values.
If you want to do a deep copy of the string values, you have to allocate them separately, eg:
void ABC::Function ()
{
CharMapT list[] =
{
{"NAME1", 1},
{"NAME2", 2},
{"NAME3", 3}
};
int num = sizeof(list) / sizeof(CharMapT);
structList = new CharMapT[num];
for (int i = 0; i < num; ++i)
{
int len = strlen(list[i].name);
structList[i].name = new char[len+1];
strcpy(structList[i].name, list[i].name);
structList[i].name[len] = 0;
structList[i].id = list[i].id;
}
...
for (int i = 0; i < num; ++i)
delete[] structList[i].name;
delete[] structList;
}
I'd like to add to #EdS.'s answer:
Your code is just much more c++ than c-style c++ code if you do it like this:
#include<string>
#include<vector>
struct CharMap
{
CharMap(const std::string& name, unsigned char id); // only needed if you don't use -std=c++11
std::string name;
unsigned char id;
};
CharMap::CharMap(const std::string& name, unsigned char id):
name(name),
id(id)
{}
class ABC
{
public:
ABC(); // or ABC() = default; if you use -std=c++11
void Function();
private:
std::vector<CharMap> structList;
}
ABC::ABC(){} // not needed with -std=c++11
void ABC::Function ()
{
// This works with -std=c++11:
//structList =
//{
// {"NAME1", 1},
// {"NAME2", 2},
// {"NAME3", 3}
//};
// without c++11:
structList = std::vector<CharMap>(3);
structList[0] = CharMap("NAME1",1); // don't worry about copies, we have RVO (check wikipedia or SO)
structList[1] = CharMap("NAME2",2);
structList[2] = CharMap("NAME2",3);
}
Why not using std::vector for making an array? You can do that like this:
#include<vector>
std::vector<CharMapT> structList(list.size());
It is safer, too, avoiding using pointers decreases the chance of memory leaks or bugs arising due to wrongly using the sizeof operator.
I suppose you do not really want a structList, that has as many elements as the memory size of your list. (If list is double this could be many times more than the number of elements in your list.)
Also, memcpy is really not necessary, if list is also a vector (that is a c function really). You just do a simple assign operation:
structList = list; // given that list is a vector.
This will copy the elements like memcpy.

Variable sized packet structs with vectors

Lately I've been diving into network programming, and I'm having some difficulty constructing a packet with a variable "data" property. Several prior questions have helped tremendously, but I'm still lacking some implementation details. I'm trying to avoid using variable sized arrays, and just use a vector. But I can't get it to be transmitted correctly, and I believe it's somewhere during serialization.
Now for some code.
Packet Header
class Packet {
public:
void* Serialize();
bool Deserialize(void *message);
unsigned int sender_id;
unsigned int sequence_number;
std::vector<char> data;
};
Packet ImpL
typedef struct {
unsigned int sender_id;
unsigned int sequence_number;
std::vector<char> data;
} Packet;
void* Packet::Serialize(int size) {
Packet* p = (Packet *) malloc(8 + 30);
p->sender_id = htonl(this->sender_id);
p->sequence_number = htonl(this->sequence_number);
p->data.assign(size,'&'); //just for testing purposes
}
bool Packet::Deserialize(void *message) {
Packet *s = (Packet*)message;
this->sender_id = ntohl(s->sender_id);
this->sequence_number = ntohl(s->sequence_number);
this->data = s->data;
}
During execution, I simply create a packet, assign it's members, and send/receive accordingly. The above methods are only responsible for serialization. Unfortunately, the data never gets transferred.
Couple of things to point out here. I'm guessing the malloc is wrong, but I'm not sure how else to compute it (i.e. what other value it would be). Other than that, I'm unsure of the proper way to use a vector in this fashion, and would love for someone to show me how (code examples please!) :)
Edit: I've awarded the question to the most comprehensive answer regarding the implementation with a vector data property. Appreciate all the responses!
This trick works with a C-style array at the end of the struct, but not with a C++ vector. There is no guarantee that the C++ vector class will (and it most likely won't) put its contained data in the "header object" that is present in the Packet struct. Instead, that object will contain a pointer to somewhere else, where the actual data is stored.
i think you might want to do like this:
`
struct PacketHeader
{
unsigned int senderId;
unsigned int sequenceNum;
};
class Packet
{
protected:
PacketHeader header;
std::vector<char> data;
public:
char* serialize(int& packetSize);
void deserialize(const char* data,int dataSize);
}
char* Packet::serialize(int& packetSize)
{
packetSize = this->data.size()+sizeof(PacketHeader);
char* packetData = new char[packetSize];
PacketHeader* packetHeader = (PacketHeader*)packetData;
packetHeader->senderId = htonl(this->header.senderId);
packetHeader->sequenceNum = htonl(this->header.sequenceNum);
char* packetBody = (packetData + sizeof(packetHeader));
for(size_t i=0 ; i<this->data.size() ; i++)
{
packetBody[i] = this->data.at(i);
}
return packetData;
}
void deserialize(const char* data,int dataSize)
{
PacketHeader* packetHeader = (PacketHeader*)data;
this->header.senderId = ntohl(packetHeader->senderId);
this->header.sequenceNum = ntohl(packetHeader->sequenceNum);
this->data.clear();
for(int i=sizeof(PacketHeader) ; i<dataSize ; i++)
{
this->data.push_back(data[i]);
}
}
`
those codes does not include bound checking and free allocated data, don't forget to delete the returned buffer from serialize() function, and also you can use memcpy instead of using loop to copy byte per byte into or from std::vector.
most compiler sometime add padding inside a structure, this would cause an issue if you send those data intact without disable the padding, you can do this by using #pragma pack(1) if you are using visual studio
disclaimer: i don't actually compile those codes, you might want to recheck it
I think the problem centres around you trying the 'serialise' the vector that way and you're probably assuming that the vector's state information gets transmitted. As you've found, that doesn't really work that way as you're trying to move an object across the network and things like pointers etc don't mean anything on the other machine.
I think the easiest way to handle this would be to change Packet to the following structure:
struct Packet {
unsigned int sender_id;
unsigned int sequence_number;
unsigned int vector_size;
char data[1];
};
The data[1] bit is an old C trick for variable length array - it has to be the last element in the struct as you're essentially writing past the size of the struct. You have to get the allocation for the data structure right for this, otherwise you'll be in a world of hurt.
Your serialisation function then looks something like this:
void* Packet::Serialize(std::vector<char> &data) {
Packet* p = (Packet *) malloc(sizeof(Packet) + data.size());
p->sender_id = htonl(this->sender_id);
p->sequence_number = htonl(this->sequence_number);
p->vector_size = htonl(data.size());
::memcpy(p->data, data[0], size);
}
As you can see, we'll transmit the data size and the contents of the vector, copied into a plain C array which transmits easily. You have to keep in mind that in your network sending routine, you have to calculate the size of the structure properly as you'll have to send sizeof(Packet) + sizeof(data), otherwise you'll get the vector cut off and are back into nice buffer overflow territory.
Disclaimer - I haven't tested the code above, it's just written from memory so you might have to fix the odd compilation error.
I think you need to work directly with byte arrays returned by the socket functions.
For these purposes it's good to have two distinct parts of a message in your protocol. The first part is a fixed-size "header". This will include the size of the byes that follow, the "payload", or, data in your example.
So, to borrow some of your snippets and expand on them, maybe you'll have something like this:
typedef struct {
unsigned int sender_id;
unsigned int sequence_number;
unsigned int data_length; // this is new
} PacketHeader;
So then when you get a buffer in, you'll treat it as a PacketHeader*, and check data_length to know how much bytes will appear in the byte vector that follows.
I would also add a few points...
Making these fields unsigned int is not wise. The standards for C and C++ don't specify how big int is, and you want something that will be predictable on all compilers. I suggest the C99 type uint32_t defined in <stdint.h>
Note that when you get bytes from the socket... It is in no way guaranteed to be the same size as what the other end wrote to send() or write(). You might get incomplete messages ("packets" in your terminology), or you might get multiple ones in a single read() or recv() call. It's your responsibility to buffer these if they are short of a single request, or loop through them if you get multiple requests in the same pass.
This cast is very dangerous as you have allocated some raw memory and then treated it as an initialized object of a non-POD class type. This is likely to cause a crash at some point.
Packet* p = (Packet *) malloc(8 + 30);
Looking at your code, I assume that you want to write out a sequence of bytes from the Packet object that the seralize function is called on. In this case you have no need of a second packet object. You can create a vector of bytes of the appropriate size and then copy the data across.
e.g.
void* Packet::Serialize(int size)
{
char* raw_data = new char[sizeof sender_id + sizeof sequence_number + data.size()];
char* p = raw_data;
unsigned int tmp;
tmp = htonl(sender_id);
std::memcpy(p, &tmp, sizeof tmp);
p += sizeof tmp;
tmp = htonl(sequence_number);
std::memcpy(p, &tmp, sizeof tmp);
p += sizeof tmp;
std::copy(data.begin(), data.end(), p);
return raw_data;
}
This may not be exactly what you intended as I'm not sure what the final object of your size parameter is and your interface is potentially unsafe as you return a pointer to raw data that I assume is supposed to be dynamically allocated. It is much safer to use an object that manages the lifetime of dynamically allocated memory then the caller doesn't have to guess whether and how to deallocate the memory.
Also the caller has no way of knowing how much memory was allocated. This may not matter for deallocation but presumably if this buffer is to be copied or streamed then this information is needed.
It may be better to return a std::vector<char> or to take one by reference, or even make the function a template and use an output iterator.