C++/Pointer to a Structure/ validate members - c++

below is my structure which i expose to user to populate it by giving it some size using malloc.
the use passes me the pointer to this structure
typedef struct ServerConfiguration {
wchar_t *IPAddress;
USHORT PortNo;
wchar_t *Title;
int repeatCount;
int timeout;
} ServerConfig;
ServerConfig *serverconfig = (ServerConfig*)malloc(sizeof(ServerConfig));
dcmServerconfig->IPAddress = L"localhost";
dcmServerconfig->Title = L"DVTK_MW_SCP";
dcmServerconfig->PortNo = 8080;
user doe not assign repeat count//
which points to some junk address loc //example repeatCount=380090700
i have another structure which has struct,
typedef struct CommonParameters {
//other members;
int repeatCount
} commonParams;
i have to validate ServerCOnfig values and then assign it to CommonParameters as show below
if (serverConfig->opt_repeatCount > 1) {
commonParams.repeatCount = serverConfig->repeatCount;
}
The value of serverConfig->repeatCount is some junk(380090700) if not assigned by user. and which is greater than 1 in my case. I need to validate if this serverConfig->repeatCount is having a valid value then only pass the if condition
Ultimately my question is to validate a structure variable which is integer for a proper value.

Your code looks like it's written in a very C-based style (i.e. allocating a chunk of memory with malloc and then initializing the struct's fields manually). If you adopt a more common C++-based style where you use new to allocate your memory and constructors to initialize your fields you'll find these kinds of problems become easier. For example, in your case you could write CommonParameters as:
struct CommonParameters {
CommonParameters(int rc) :
repeatCount(rc)
{}
//other members;
int repeatCount
};
This way CommonParameters is initialized when it's created and you don't have to worry about its initialization status.
NOTE: Because your question is written in what looks like pure C you may have just mis-tagged the question as C++. If so, please change the tag and I'll update my answer.

Related

What is the best way to initialize a more complex class construct with many unchangeable members in c++

I'm currently designing classes that should represent a chaotic storage system.
Lets say we have slots in rows and columns with certain properties.
So the slots have different restrictions in min/max height, width, length, weight and some more that come from a parameter file.
Also the Slots have a max total weight that must be checked before a new parcel gets added to that slot. And also the max weight that a row of slots can hold is lower than the sum of the max weights of the single slots. So for example each individual slot might be able to hold 50kg but the row of 10 slots must not exceed 200kg, so it is not allowed to fill every slot by 100%. The same is true for the Columns where the maximum weight is lower than the sum of the individual weights of the single rows. The row_id and column_id are atrificial numbers for adressing the slot in the physical system with barcodes or whatever that get read for positioning.
As all this parameters do not change over the lifetime of the program, my intention was to design the classes in a way that this properties are readable by getter functions but there should not be any setter functions (maybe not even private ones) in the object o the values cannot be changed by accident.
There is one class/function that reads the config-file and generates the data structure for the rows and columns with the slots. This function should be able to read the config and create objects for every column holding a row of slots and pass all the values from the config down to the slot.
Later when the program is running I also need some way to search for the best matching slot to add the next parcel or for searching parcels and unload them in a certain sequence.
So the (simplfied) basic structure of the classes would be like this:
Class Parcel {
int width;
int height;
int length;
int weight;
}
Class Slot {
vector<Parcel> parcel;
int min_width;
int max_width;
int min_height;
int max_height;
int min_length;
int max_length;
int max_total_weight;
int act_total_weight;
int total_length;
int free_length;
}
Class Row {
vector<Slot> slot;
int row_id;
int max_total_weight;
int act_total_weight;
}
Class Column {
vector<Row> row;
int column_id;
int max_total_weight;
int act_total_weight;
}
Class Storage {
vector<Column> column;
}
So here are my thoughts about how to initialize the data structure:
First possibility would be to pass all the properties in the constructor(s) of the classes, but then the constructors has some huge parameter lists specially for the Slot class that has a lot of properties.
Second thing that came to my mind (and currently my fafourite way to go) is to use config-data-structures that hold all the parameters. This parameter-objects get filled by the config-function and passed to the constructor when initializing the class. Then it also may be useful to use the parameter class as such and not having all the parameters defined in the storage class once more.
Third way is to use private setter and public getter and make the config class friends with the data structure classes to be able to access the setter functions (but i would prefer to have no setters at all in the final storage structure classes.
Fourth way that i was thinking off, was to derive child classes from the structure classes that hold the setter functions (and also some other logic needed for creating the data structure) so the child has no own variables but only additional functions. So the child class is used to fill the properties but the base class gets added to the data structure vector.
I also want to use Factory pattern to initialize the data structure because the objects have often similar or only slightly different properties. So with the second aproach after creating one row of slots I would maybe want to change the max weight of the slots in that row. Therefore I would need to change the setting in the factory and the factory then fills the parameter data structure differently and passes it to the Slot class. Or is it better to pass the data structure to the factory directly and the factory assigns it but then i think this is not what the factory pattern is meant to be.
I don't know if this is a good aproach or which of the above is best practice.
Or am I missing something and there is a way more convenient solution or this?
Thank you (and sorry if the question is maybe not the way it should be)
When constructing your classes as you describe it you can have a look at the creational design patterns.
Your second proposed solution is almost a builder design pattern. This will help you to construct the Slot e.g. piecewise.
As an example:
#include <iostream>
class Slot {
public:
int GetMinWidth() const { return min_width_; };
int GetMaxWidth() const { return max_width_; };
// Builder class
class SlotBuilder {
public:
SlotBuilder& SetMinWidth(int min_width) {
min_width_ = min_width;
return *this;
}
SlotBuilder& SetMaxWidth(int max_width) {
max_width_ = max_width;
return *this;
}
Slot Build() {
return Slot(min_width_, max_width_);
}
private:
int min_width_{/* you can add default value here*/};
int max_width_{/* you can add default value here*/};
};
// This is optional, but creates a neat interface
static SlotBuilder Create() {
static SlotBuilder slot_builder;
return slot_builder;
}
private:
// Make constructor private to restrict access and force the use of the builder
Slot(int min_width, int max_width) : min_width_(min_width), max_width_(max_width) {}
const int min_width_;
const int max_width_;
// .
// .
// Continue with your const attributes
};
int main() {
// Create the slot with the builder
Slot slot = Slot::Create()
.SetMinWidth(10)
.SetMaxWidth(20)
.Build();
std::cout << slot.GetMinWidth() << ", " << slot.GetMaxWidth();
return 0;
}
You can see the example working here
For having different types that are almost the same a Prototype pattern could work if you want to "clone" a class or in your case a Factory pattern could do the job.
There is never an ideal solution or that one pattern that solves it all, so I can't give you a definitive answer, but here are some collected thoughts:
Default values
Primitive types like int don't have a default value, so make sure you give them one explicitly:
struct Parcel {
int width{};
int height = 0;
int length = {};
int weight{};
}
All those different versions above are equivalent, but you really should use one of them. Otherwise you will probably run into UB down the line.
Const correctness
One thing that I love about C++ and that I dearly miss in languages like C# is const correctness. If you want an object to be immutable, declare it as const. To prevent changes to your objects, either instantiate the object as a const:
const Parcel x;
x.width = 10; // compiler error
or make the members of your classes const:
struct Parcel {
const int width{};
const int height{};
const int length{};
const int weight{};
};
Parcel x;
x.width = 10; // compiler error
Aggregate initialization
If you keep your types simple enough you can initialize the class members with curly braces directly:
const Parcel x { 1, 2, 3, 4 };
In C++ 20, you can also name the members, so this code is equivalent to the line above:
const Parcel x { .width = 1, .height = 2, .length = 3, .weight = 4 };
Note that this can bite you later though if you have to deal with ABI stability and versioning. In that case you are better off using getter and setter functions, because that allows you to still change the data layout of your members.
I have to think about design patterns a bit more. I'll update this post if something useful comes out of it.

Nested array of structs - how do i properly assign a value to struct members?

I have
struct Voice {
static byte mode;
//Some other stuff
};
byte Voice::mode{}; //Static member defined outside of struct declaration
and
struct DataPacket {
DataPacket() : sequencer{}, voice{}, tempdata{} {};
Sequencer sequencer;
Voice voice[4];
Tempdata tempdata;
};
I want to assign one of the voice struct members in the array with a variable value like this:
DataPacket assignVoiceValues(const InputPacket &inputPacket,
DataPacket &dataPacket,
const byte &voiceNumber) {
dataPacket.voice[voiceNumber].mode = (byte) inputPacket.finalPotvalue[0];
//Other code
}
Even though this compiles, when i test the code all of the four structs members mode in the voice[] array are simultaneously assigned with inputPacket.finalPotvalue[0]. There is no code for assigning values to dataPacket.voice[voiceNumber].mode elsewhere that could possibly interfere.
I have no idea why this is happening. What am i missing, and what is the proper syntax for making it work as intended?
(I know vectors generally are recommended over arrays, but the code is intended for an arduino board with limited memory).
You have define mode as static byte mode;... So there's space allocated for exactly one of them in the entire program.
Perhaps mode should not be marked as static?
Since you declare variable "mode" static it is bound to your class (which is single), not to instances of your class (you can create a lot of instances).
To fix the problem just remove static from description of your variable
https://en.cppreference.com/w/cpp/language/static

Packet cast to struct with multiple dynamic arrays

I'm currently working on a Client/Server application, sending packets via TCP.
To read the incoming packet, I do something like this:
struct SomeRandomStruct
{
int nVal1;
int nVal2;
};
SomeRandomStruct* pStruct = reinterpret_cast<SomeRandomStruct*>(pBuffer);
Right now there's a small problem. Let's say I have a struct like this
struct SomeNewStruct
{
int nNameLen;
int nPassLen;
char szName[];
char szPass[];
};
Since the size/length of szName & szPass is sent in the same packet, is there a way I can set its size ,,within the reinterpret_cast" or do I have to read the packet manually?
Friendly warning:
stop!
Consider something like google protocol buffers to encode messages for you in a cross-platform and safe way.
Here are some reasons why:
How big is an int? On your machine? today? tomorrow? It's undefined in the c++ standard.
What is the binary representation of an int? Is it the same on the machine sending and the machine receiving? Will it always be? (If you think 'yes' then you're wrong). Again the c++ standard has nothing to say on the matter.
What is the padding between data members in the struct? Is it the same for all compilers on all hosts? (answer: no)
ask yourself why functions like htons() exist. They are there because not all machines are the same, but the communication between them must be.
I could go on...
As your question is tagged C++, I'd propose you to do dynamic allocation in constructor and deallocation in destructor. That way, you could have simply pointers in your struct :
struct struct SomeNewStruct {
int nNameLen;
int nPassLen;
char *szName;
char *szPass;
SomeNewStruct(int nameLen , int passLen) {
// set and alloc...
}
SomeNewStruct(SomeNewStruct &src) {
// alloc and copy
}
~SomeNewStruct() {
// dealloc ...
}
}
You could even use std::string for szName and SzPass letting the STL deal with those low level allocation details :
struct struct SomeNewStruct {
int nNameLen;
int nPassLen;
std::string szName;
std::string szPass;
}

Convert class from C++ to Delphi

I'm trying to convert a C++ project to Delphi, but I don't know how to convert these two classes:
class CData;
class CContext;
class CData
{
public:
CContext* Data;
};
class CContext
{
public:
char Unk[2240];
DWORD data1;
DWORD data2;
DWORD data3;
};
Usage:
CData* Data = (CData*)(0x00112233);
//This code obtain the bytes in memory of the address "0x00112233" based on the sizes specified at CContext class
Please, if someone knows, help-me.
Thank you.
The class is just a simple compound structure. That's a record in Delphi:
type
TData = record
unk: array [0..2240-1] of AnsiChar;
data1, data2, data3: DWORD;
end;
Your context type is just a pointer to that:
type
TContext =^TData;
In the C code this pointer is wrapped in a class which seems a little pointless to me.
Declare a variable that is a pointer to TContext:
var
context: ^TContext;
Assign it like this:
context := Pointer($00112233);
It looks like your CContext class is nothing more than a 2240 length string with 3 double-words of reserved space (likely that is never used). CData is nothing more than a pointer to an instance of CContext. To be more specific about how to port these, you would need to give more specifics on how they are used. As it stands right now, you could likely just implement a version of CData that has a string member.

C++ Struct - Define Minimum Size

Is there a C++ (or MSVC) method of automatically padding a struct to a minimum size? For example, imagine the following pseudo-code:
#pragma pad(256) // bytes
struct SETUPDATA {
int var1;
double var2;
};
where sizeof(SETUPDATA) = 256 bytes
The goal here being, during development this struct's members can change without changing the footprint size at runtime.
You can use a union
struct SETUPDATA {
union { struct your_data; char [256]; }
}
or something like this. This ensures it's at least 256 but only as long as your_data is not larger.
You can also add a simple assert after that just does a compiler check assert(sizeof(struct SETUPDATA) == 256)
One way is to inherit from your "real" structure and use sizeof() to make up the padded structure, for example:
struct blah_real
{
int a;
};
struct blah : public blah_real
{
private:
char _pad[256 - sizeof(blah_real)];
};
You could use #ifdef DEBUG to only do this in the debug build and just use the real structure in release build.
The first thing you have ot ask yourself is why your application cares if the struct size changes. That indicate fragility to future changes and your design may be better served by instead allowing the application to seamlessly work in the face of struct size changes.
Perhaps you're trying to serialize the data directly and don't want to face changes in the format, but in that case you're already tying yourself to one specific representation of the structure in memory. For example support the size of one of the builtin-type members changes due to a compiler upgrade or options.
But let's say you really do want to do this.
Just wrap the data in an impl and pad the real struct:
struct SetupData
{
struct Impl
{
int var1;
double var2;
};
Impl impl_;
unsigned char pad_[256 - sizeof(Impl)];
};