Copy two similar structures in C++ - c++

I want to copy two similar structures in C++. Consider the below three structures.
struct Dest_Bio
{
int age;
char name;
};
struct Source_Bio
{
int age;
char name;
};
struct Details
{
int id;
Dest_Bio* st_bio; //Needs to be populated with values from Source_Bio
};
I have values filled in 'Source_Bio' structure
I want to copy these values in Source_Bio into st_bio in 'Details' structure.
I do not want to create a member for Dest_Bio
I tried the following. It compiles fine but crashes the program on run time.
Source_Bio st_ob;
st_ob.age = 5;
st_ob.name = 't';
Details st_a;
st_a.id = 1;
st_a.st_bio = (Dest_Bio*) malloc(sizeof(Dest_Bio));
memcpy((struct Dest_Bio*)&st_a.st_bio, (struct Source_Bio*)&st_ob,sizeof(Dest_Bio));
How can I get this done? Thanks in advance

The easy way would probably be something like this:
struct Dest_Bio {
int age;
char name; // should this really be a string instead of a single char?
Dest_Bio(Source_Bio const &s) : age(s.age), name(s.name) {}
};
Details st_a;
st_a.id = 1;
st_a.st_bio = new Dest_Bio(st_ob);
Better still, you should probably just eliminate Dest_Bio and Source_Bio and replace both with just Bio and be done with it. You also almost certainly want to replace your Dest_Bio *st_bio with some sort of smart pointer -- a raw pointer is pretty much asking for trouble. Alternatively, just embed a Bio object inside the Details object (probably the preferred choice).

Since you already have the requirement that both Bio types be layout-compatible, make a common type Bio. Then do the copy in C++ rather than C:
st_a.st_bio = new Bio(st_ob);
If they do need to be different types, then you might make Source_Bio convertible to Dest_Bio via a constructor or conversion operator.
That's assuming you have a genuine reason for your third requirement (that it be a pointer rather than a member). Otherwise, make it a member, fixing the potential memory leak, and simplify the code further:
st_a.st_bio = st_ob;
If you really want to muck around with C functions, then you want to copy to st_a.st_bio, not to &st_a.st_bio (i.e. overwriting the object, not the pointer to it). Only do that if you hate whoever will be maintaining the code.

Related

How to let the compiler do the offset computations for an odd polymorphism structure, with as little code as possible?

I am not sure if this is possible at all in standard C++, so whether it even is possible to do, could be a secondary way to put my question.
I have this binary data which I want to read and re-create using structs. This data is originally created as a stream with the content appended to a buffer, field by field at a time; nothing special about that. I could simply read it as a stream, the same way it was written. Instead, I merely wanted to see if letting the compiler do the math for me, was possible, and instead implementing the binary data as a data structure instead.
The fields of the binary data have a predictable order which allows it to be represented as a data type, the issue I am having is with the depth and variable length of repeating fields. I am hoping the example code below makes it clearer.
Simple Example
struct Common {
int length;
};
struct Boo {
long member0;
char member1;
};
struct FooSimple : Common {
int count;
Boo boo_list[];
};
char buffer[1024];
int index = 15;
((FooSimple *)buffer)->boo_list[index].member0;
Advanced Example
struct Common {
int length;
};
struct Boo {
long member0;
char member1;
};
struct Goo {
int count;
Boo boo_list[];
};
struct FooAdvanced : Common {
int count;
Goo goo_list[];
};
char buffer[1024];
int index0 = 5, index1 = 15;
((FooAdvanced *)buffer)->goo_list[index0].boo_list[index1].member0;
The examples are not supposed to relate. I re-used some code due to lack of creativity for unique names.
For the simple example, there is nothing unusual about it. The Boo struct is of fixed size, therefore the compiler can do the calculations just fine, to reach the member0 field.
For the advanced example, as far as I can tell at least, it isn't as trivial of a case. The problem that I see, is that if I use the array selector operator to select a Goo object from the inline array of Goo-elements (goo_list), the compiler will not be able to do the offset calculations properly unless it makes some assumptions; possibly assuming that all preceding Goo-elements in the array have zero Boo-elements in the inline array (boo_list), or some other constant value. Naturally, that won't be the case.
Question(s):
What ways are there to achieve the offset computations to be done by the compiler, despite the inline arrays having variable lengths? Unless I am missing something, I believe templates can't help at all, due to their compile-time nature.
Is this even possible to achieve in C++?
How do you handle the case with instantiating a FoodAdvanced object, by feeding a variable number of Goo and Boo element counts to the goo_list and boo_list members, respectively?
If it is impossible, would I have to write some sort of wrapper code to handle the calculations instead?

Dynamic Memory Allocation in C++ structs

I don't understand the syntax required for dynamically allocating members of a struct in c++. Basically, I need to fill char array members to exact size using a temp array and strlen. Here is my struct:
struct card
{
char *rank;
char *suit;
char color;
bool dealt;
char *location;
};
Here is the function that uses the struct:
bool importCard(card *deckPtr, char *deckName);
I created an array of 52 cards and assigned a pointer to it, and passed it to the function as the first parameter. (deckPtr) Here is a loop in the function that is supposed to read in card info to the struct data members.
for(index=0;index<52;index++,deckPtr++)
{
fin >> *temp;
charCount=stringLength(temp);
deckPtr.*rank = new char[charCount+1];
stringCopy(*temp, deckPtr.*rank);
fin >> *temp;
charCount=stringLength(temp);
deckPtr.*suit = new char[charCount+1];
stringCopy(*temp, deckPtr.*suit);
if(deckPtr.*suit==('d')||deckPtr.*suit==('h'))
{
(*deckPtr).color='r';
}
else
{
(*deckPtr).color='b';
}
(*deckPtr).dealt=false;
deckPtr.*location = new char[11];
stringCopy(unshPtr, deckPtr.*location);
}
I am getting three compile errors: "rank" "suit" and "location" are "not declared in this scope." What am I doing wrong? Thanks!
The syntax is deckPtr->rank, deckPtr->suit, deckPtr->location = new char[...];.
But your coding style is more like C than C++. Instead, if you use modern C++, with convenient RAII classes like std::string, your code becomes much more simplified: just use std::string instead of raw char* pointers, and you don't have to pay attention to memory allocation and memory freeing: it's all automatically managed by std::string and destructors.
#include <string>
struct card
{
std::string rank;
std::string suit;
char color;
bool dealt;
std::string location;
};
And instead of your custom stringCopy() function you can just use the "natural" operator= overload for std::string (i.e. destString = sourceString;).
And to build an array of 52 cards, just use std::vector:
#include <vector>
std::vector<card> cards(52);
Again, memory allocation is automatically managed by std::vector (and, unlike raw C arrays, you can query the vector for its own element count, using its size() method).
You probably want to use deckPtr->rank, deckPtr->suit, and deckPtr->location to assign something to the char pointers (alternatively, (*deckPtr).rank etc.). Note that * in char *var is not part of the name of the variable. It just states that the variable is a pointer to char.
You need deckPtr->foo instead of deckPtr.*foo
Your problem is that the dereference operator is operating on foo, not on deckPtr, which makes no sense to the C++ compiler, so it uses instead the pointer to member operator. This operator is used to execute member function pointers on an object, which is completely different from accessing a member. Chances are good that in an intro-level c++ class (like it appears you are in) you will never have to worry about using or understanding that operator.
In general, in C/C++ whenever you have a pointer to a struct, you want to use the -> operator, not .. foo->bar is equivalent to (*foo).bar, but it keeps you from messing up and forgetting the parentheses. There's a reason that C had an arrow operator - it's easier and clearer. In my not-so-humble opinion, teachers that impose such arbitrary restrictions actually teach students to write bad code and reinvent wheels, but I don't have their experience in teaching programming...

Accessing any structs members at run-time

Is it possible to get access to an individual member of a struct or class without knowing the names of its member variables?
I would like to do an "offsetof(struct, tyname)" without having the struct name or member variable name hard coded amoungst other things.
thanks.
Sure. If you have a struct and you know the offset and the type of the member variable, you can access it using pointers.
struct my_struct {
int member1;
char member2;
short member3;
char member4;
}
...
struct my_struct obj;
short member3 = *((short*)((char*)&obj + 5));
That'll get the value of member3, which is 5 bytes on from the start of obj on an x86 computer. However, you want to be careful. First of all, if the struct changes, your data will be garbage. We're casting all over the place, so you get no type safety, and the compiler won't warn you if something's awry. You'll also need to make sure the compiler's not packing the struct to align variables to word boundaries, or the offset will change.
This isn't a pleasant thing to do, and I'd avoid it if I were you, but yes, it can be done.
C and C++ are compiled languages without built-in "reflection" features. This means that regardless of what you do and how you do it, one way or another the path will always start from an explicit hard-coded value, be that a member name or an compile-time offset value. That means that if you want to select a struct member based on some run-time key, you have no other choice but to manually create a mapping of some kind that would map the key value to something that identifies a concrete struct member.
In C++ in order to identify a struct member at run-time you can use such feature as pointers-to-members. In C your only choice is to use an offset value.
Another issue is, of course, specifying the type of the members, if your members can have different types. But you provided no details about that, so I can't say whether you need to deal with it or not.
We had a similar problem some years ago: A huge struct of configuration information that we wanted to reflect on. So we wrote a Perl script to find the struct, parse its members, and output a C++ file that looked like:
struct ConfField
{ const char* name;
int type;
size_t offset;
};
ConfField confFields[] = {
{ "version", eUInt32, 0 },
{ "seqID", eUInt32, 4 },
{ "timestamp", eUInt64, 8 },
// ... lots more ...
{ 0, 0, 0 }
};
And we'd feed the script with the output from gcc -E.
Nowadays, I understand that gccxml can output an XML file representing any C++ source that gcc can compile, since it actually uses the g++ front end to do the parsing. So I'd recommend pairing it with an XML-parsing script (I'd use Python with the lxml library) to find out everything you ever wanted to know about your C++ source.
Somewhere in your code you need to reference the data member in the struct. However you can create a variable that is a pointer to a struct data member and from then on you no longer need to reference it by name.
struct foo
{
int member1;
int member2;
};
typedef int (foo::*intMemberOfFoo);
intMemberOfFoo getMember()
{
if (rand() > RAND_MAX / 2) return &foo::member1;
else return &foo::member2;
}
foo f;
void do_somthing()
{
intMemberOfFoo m = getMember();
f.*m = 0;
}
The technical answer is 'yes' because C++ is Turing-complete and you can do almost anything if you try hard enough. The more practical answer is probably 'no' since there is no safe and easy way of doing exactly what you want.
I agree with GMan. What exactly are you trying to do that makes you think you need this technique?
Well you will have to set up some stuff first, but it can be done. Expanding on Samir's response
struct my_struct {
int member1;
char member2;
short member3;
char member4;
}
you can create a table of offsets:
my_struct tmp;
int my_struct_offsets[4]={
0,
(char*)&(tmp.member2)-(char*)&(tmp.member1),
(char*)&(tmp.member3)-(char*)&(tmp.member1),
(char*)&(tmp.member4)-(char*)&(tmp.member1)
}
this will take into account different alignments on different systems

C++ malloc - dynamic array

Assuming that I have a program that has an array of unknown lenght that consists of Customers.
Here, a customer struct:
struct Customer
{
char* lastname;
char* firstname;
int money;
};
And here - an array:
Customer* CustomerDB;
Okay. But the thing is that I want to add and remove customers dynamically during runtime. I don't want to allocate like 100 customers during declaration or during runtime - I want to allocate one at a time when it is needed.
Think of a simple AddCustomer function that allocates memory, enters the given data and then increments a counter (which is probably needed for iteration).
This is my main problem.
What I want is the array to behave exactly like one that has been declared with 100 arrays instead of a dynamical one.
The customer program above is just an example, please don't tell me that it's a bad idea to do that and that or that.
How do I create an AddCustomer function working for the code above?
It is necessary that I can iterate through CustomerDB
Use standard template library std::vector or a vector of pointers.
Use a standard library container, such as vector, deque, or list.
I suppose the AddCustomer function might be implemented like this:
void AddCustomer(Customer** db, int current_count);
where the memory re-allocation might be done in terms of realloc.
However, you do realize that you are not taking advantage of anything that C++ offers, so you could have just posted this as a C question (in C++ this is a no-brainer with vector/deque/list and push_back)?
If you can use std::vector or similar, use that, they're purpose-built for this sort of problem. I'd also replace the raw char * with std::string at the same time.
If you're stuck with the approach above, you might want to change the size of the allocated array using realloc() when the size changes. However that's a very manual way of implementing what a combination of vector & string can do for you much easier and without potential resource leaks.
Here are just some thoughts
Judging from your requirements it sounds as if you would be better off with a list than an array. A list would fit more natural to your requirements regarding the dynamics and having no max limit.
Either you could create your own linked list using a pointer in each list element or use std::dequeue or similar however you would anyway need to take care of what the pointers inside your struct are pointing to. Simplest case in your example would probably to use std::string instead of pointers - then the strings are automatically copied and you don't have to concern yourself with the memory (or use boost::shared_array as pointers).
struct Customer
{
string lastname;
string firstname;
int money;
};
Just my 2c
As you suggested, this is not the "Correct" way to do things - but heres what you asked for.
typedef struct _tag_Customer {
char *LastName;
char *FirstName;
double Money;
} CUSTOMER, *LPCUSTOMER;
typedef struct _tag_Customers {
CUSTOMER *Collection;
int Count;
} CUSTOMERS, *LPCUSTOMERS;
LPCUSTOMER AddCustomer(LPCUSTOMERS pCustomers, const char *sLastName, const char *sFirstName, double dMoney)
{
int iRequiredMemory = (sizeof(CUSTOMER) * (pCustomers->Count + 1));
if(!(pCustomers->Collection = (LPCUSTOMER) realloc(pCustomers->Collection, iRequiredMemory)))
{
return NULL; //Memory allocation error.
}
LPCUSTOMER pCutsomer = &pCustomers->Collection[pCustomers->Count];
pCustomers->Count++;
iRequiredMemory = strlen(sLastName) + 1;
pCutsomer->LastName = (char *) calloc(iRequiredMemory, sizeof(char));
strcpy(pCutsomer->LastName, sLastName);
iRequiredMemory = strlen(sFirstName) + 1;
pCutsomer->FirstName = (char *) calloc(iRequiredMemory, sizeof(char));
strcpy(pCutsomer->FirstName, sLastName);
pCutsomer->Money = dMoney;
return pCutsomer;
}
void main(void)
{
CUSTOMERS Database;
memset(&Database, 0, sizeof(CUSTOMERS));
AddCustomer(&Database, "Smith", "Joe", 100.99);
AddCustomer(&Database, "Jackson", "Jane", 100.99);
AddCustomer(&Database, "Doe", "John", 100.99);
//You'll need to free the Memory, of course.
}

Getting the size in bytes or in chars of a member of a struct or union in C/C++?

Let's say that I want to get the size in bytes or in chars for the name field from:
struct record
{
int id;
TCHAR name [50];
};
sizeof(record.name) does not work.
The solution for this is not so pretty as you may think:
size_in_byte = sizeof(((struct record *) 0)->name)
size_in_chars = _countof(((struct record *) 0)->name)
If you want to use the second one on other platforms than Windows try:
#define _countof(array) (sizeof(array)/sizeof(array[0]))
If you create an instance first, it will work.
record r;
sizeof(r.name);
In C++:
#include <iostream>
using namespace std;;
struct record
{
int id;
char name [50];
};
int main() {
cout << sizeof( record::name) << endl;
}
Edit: A couple of people have pointed out that this is C++0x code, so I guess I must retract my unkind comment regarding VC++. This is not a programming construct I have ever used in my own C++ code, but I have to wonder why sizeof would not work this way in C++03? You hand it a name and it gives you the size. I'd have thought it would take some effort for it not to work. But such is the wonder of the C++ Standard :-)
record is the name of a type, but record.name is not. You somehow have to access name through an instance of the struct. Sorin's answer is the usual C solution:
sizeof ((struct record*)0)->name;
This creates a pseudo-pointer to an instance (or pointer to a pseudo-instance) of struct record, then access the name member, and pass that expression to sizeof. It works because sizeof doesn't attempt to evaluate the pointer expression, it just uses it to compute the size.
You might wanna read this, as it discusses the very same issue and provides all the options mentioned in this thread, and a little more.
struct record
{
static const int kMaxNameChars=50;
int id;
TCHAR name [kMaxNameChars];
};
sizeof(TCHAR)*record::kMaxNameChars //"sizeof(record.name)"
//record::kMaxNameChars sufficient for many purposes.
Portable, perfectly safe and IMO being explicit about raw array length is good practice.
(edit: you might have to macro it in C, if the compiler gets upset about variable array lengths. if you do, consider defining a static const int to the value of the macro anyway!)