Allocate space in struct for char* array - arrays

I am trying to allocate space inside a struct. This struct contains information of a network packet.
The structure:
struct STRUCT_SVC_ROOM_CREATE
{
PacketHeader Header;
unsigned char TitleLength;
char* RoomTitle = new char[TitleLength];
short SuddenFactor;
short GameModeFactor;
unsigned char Password[4];
int MaxMen;
};
See this two lines of code
unsigned char TitleLength;
char* RoomTitle = new char[TitleLength];
1st -> The length of text (1 byte)
2nd -> The text itself (TitleLength bytes)
And this is how I create the struct based into another.
STRUCT_SVC_ROOM_CREATE* RoomCreate = (STRUCT_SVC_ROOM_CREATE*)pHeader;
pHeader is another struct, this contains all the information. Then I put into another struct to get the right data location.
But it doesnt work. So the question: How to allocate space correctly and build the struct char* with the size specified in TitleLength?

You shouldnt initialise the object inside the struct definition.
struct STRUCT_SVC_ROOM_CREATE
{
PacketHeader Header;
unsigned char TitleLength;
char* RoomTitle;
short SuddenFactor;
short GameModeFactor;
unsigned char Password[4];
int MaxMen;
};
void someFunction()
{
STRUCT_SVC_ROOM_CREATE* foo = new STRUCT_SVC_ROOM_CREATE;
foo->TitleLength = 10;
foo->RoomTitle = new char[foo->TitleLength];
}
Here is the requested class implementation (not tested):
class SVC_ROOM_CREATE{
private:
PacketHeader Header;
char* RoomTitle;
short SuddenFactor;
short GameModeFactor;
unsigned char Password[4];
int MaxMen;
public:
SVC_ROOM_CREATE(PacketHeader packet_header, int length, short sud_factor, short gm_factor, unsigned char pwd[], int max)
{
Header = packet_header;
RoomTitle = new char[length];
SuddenFactor = sud_factor;
GameModeFactor = gm_factor;
memcpy( Password, pwd, sizeof(Password));
MaxMen = max;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
PacketHeader Header;
unsigned char bar[4] = "pas";
int TitleLength = 10;
int SuddenFactor = 1;
int GameModeFactor = 2;
int MaxMen = 15;
SVC_ROOM_CREATE* foo = new SVC_ROOM_CREATE(Header, TitleLength, SuddenFactor, GameModeFactor, bar, MaxMen);
return 0;
}

Related

I want to access a general struct field inside another struct's field in C

I have a struct defined like this:
typedef struct {
char id[20];
char descrizione[250];
char tipoSet[30];
int scatoleDisponibili;
float costo;
} Set;
I have another struct called Complex in which I want a field to store an array of only Set struct IDs.
typedef struct {
char idComplesso[20];
content[10];
int dimLogica;
} complex;
So, I want the content array (of max size 10) to be able to store only the string id from a max of 10 Set.
How could I do this in C?
typedef struct {
char id[20];
char descrizione[250];
char tipoSet[30];
int scatoleDisponibili;
float costo;
} Set;
typedef struct {
char idComplesso[20];
int dimLogica;
size_t nsets;
char *content[];
} complex;
complex *assign(Set *s, size_t nsets)
{
complex *cml = malloc(sizeof(*cml) + nsets * sizeof(cml -> content[0]));
/* allocation check */
cml -> nsets = nsets;
for(size_t i = 0; i < nsets; i++)
{
cml -> content[i] = s[i].id;
}
return cml;
}
You'll have to make the content array be an array of char* and when you create the structure only accept id from a Set struct.
Something like this:
complex* createComplex(Set* sets) {
complex* comp = (complex*)malloc(sizeof(complex));
for (int i=0; i<10; i++) {
comp->content[i] = sets[i].id;
}
return comp;
}
And don't let any other function create the comp struct

Pass String array and indexes using Struct to a thread in C

I am trying to pass a string array and indexes from where to start end searching in the array, I am unable to solve it from the last two days. I am sending to the pthread_create a struct data thread_data, here i am able to send the int and long data, but not the string array, can someone help me, how to pass these.
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
char * str;
};
struct data thread_data[NUM_THREADS];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
char * str[3];
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
.....
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
...
char work[]={"First Line","Second line","Third line"};
...
while(fgets(arr[index],120, fp)!=NULL){
index=index+1;
thread_data[index].tid=index;
thread_data[index].str=work;
...
rc=pthread_create(&threads[index],NULL,searchString,(void *)&thread_data[index]);
...
}
pthread_exit(NULL);
}
To hold the multiple strings you need 2D array.
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
You need to use pointer to pointer in struct data to hold the above array.
struct data{
.....
const char **str;
size_t lenOfStr;
};
And pass the length of array explicitly to thread function from main function.
Your sample code may look like below.
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
const char **str;
size_t lenOfStr;
};
struct data thread_data[3];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
const char **str = NULL;
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
int i = 0;
for (i = 0;i<t_data->lenOfStr;i++)
printf("%s\n", str[i]);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
int index = 0;
pthread_t threadid=0;
thread_data[index].tid=index;
thread_data[index].str=work;
thread_data[index].lenOfStr = sizeof(work)/sizeof(*work); // Calculate the size of work here
int rc=pthread_create(&threadid,NULL,searchString,&thread_data[index]);
pthread_exit(NULL);
}

Freeing a pointer to a string in a structure [in C]

i'm trying to find the most efficient way to use the 'free' command in a program I made. Basically there are several structers, the first is called Operation. Here's how it's defined -
struct Operation {
unsigned int ic;
unsigned int dc;
struct symbolStruct *externHead;
struct symbolStruct *symbolHead;
struct DataCode *dataHead;
struct MachineCode *machineHead;
int linenumber;
};
It has several pointers to other structers, let's take machineHead for example.
struct MachineCode {
unsigned int row : WORD_SIZE;
unsigned int line;
OperandType *structure;
struct MachineCode *next;
};
And OperandType looks like this -
typedef struct {
unsigned int numOfOperands : 2;
unsigned int addrMethSou : 2;
unsigned int addrMethDest : 2;
unsigned int operation : 4;
unsigned int extraWords : 2;
char *firstOperand;
char *secondOperand;
} OperandType;
What I want to do is to free the strings "firstOperand" and "secondOperand" in structure (which is in machineHead ) and then to free machineHead itself, I tried to write it down using the following code -
void clear(struct Operation *op) {
struct MachineCode *mh = op->machineHead, *fmh;
while(mh != NULL) {
fmh = mh;
mh = mh->next;
free(fmh->structure->firstOperand);
free(fmh->structure->secondOperand);
free(fmh->structure);
free(fmh);
}
But the program crashes in runtime. Is there an elegant way to do it or do I have to make a pointer varibale of every type in order to clear the memory?

Define a structure that contains a data array and some pointers to the same data array areas

I want to define a structure that contains a data array and some pointers to the same data array. So I defined the structure and then I initialize the pointer like this:
typedef struct {
unsigned char data[MAX_PACKET_DATA];
unsigned char* sector1;
unsigned char* sector2;
unsigned char* sector3;
} Packet;
[...]
NGSCTransmittingDataPacket packet
[...]
packet->sector1 = packet.data + SECTOR1_OFFSET;
packet->sector2 = packet.data + SECTOR2_OFFSET;
packet->sector2 = packet.data + SECTOR3_OFFSET;
Can I initialize the pointer directly inside the typedef struct definition? If I write
typedef struct {
unsigned char data[MAX_PACKET_DATA];
unsigned char* sector1 = data + SECTOR1_OFFSET;
unsigned char* sector2 = data + SECTOR2_OFFSET;
unsigned char* sector3 = data + SECTOR3_OFFSET;
} Packet;
the compiler gives me error.
Any solution?
you cannot do that, C won't allow it. But in your example you could do that equivalent:
typedef struct {
unsigned char data[SECTOR1_OFFSET];
unsigned char sector1[SECTOR2_OFFSET-SECTOR1_OFFSET];
unsigned char sector2[SECTOR3_OFFSET-SECTOR2_OFFSET];
unsigned char sector3[MAX_PACKET_DATA-SECTOR3_OFFSET];
} Packet;
There's no padding since all members are char arrays.
You normally cannot go further SECTOR1_OFFSET-1 for an index of data, but there it would work (or create an union with a MAX_PACKET_DATA-length array if you want to make it cleaner, because some compilers could complain if you're accessing data with a bigger index)
Example with an union of 2 anonymous structures:
#include <stdio.h>
#define SECTOR1_OFFSET 20
#define SECTOR2_OFFSET 50
#define SECTOR3_OFFSET 80
#define MAX_PACKET_DATA 100
typedef union
{
struct
{
unsigned char sector0[SECTOR1_OFFSET];
unsigned char sector1[SECTOR2_OFFSET-SECTOR1_OFFSET];
unsigned char sector2[SECTOR3_OFFSET-SECTOR2_OFFSET];
unsigned char sector3[MAX_PACKET_DATA-SECTOR3_OFFSET];
};
struct
{
unsigned char data[MAX_PACKET_DATA];
};
} Packet;
int main()
{
Packet p;
p.data[SECTOR3_OFFSET] = 'a';
p.data[SECTOR3_OFFSET+1] = 'z';
p.data[SECTOR3_OFFSET+2] = '\0';
printf("sector 3 %s\n",p.sector3);
return 0;
}
result:
sector 3 az

how to pass enum value into structure

My problem is I need to pass value from argument (instType, typ1, *op1...) to the structure type tInst.
I'm sure it's a trivial problem but I've spent about 3 hours of my time working on it.
GCC returns segmentation fault 11.
my .h file
typedef enum tInstCode {
I_ADD=0, // (dest, addr, addr) +
I_SUB, // (dest, addr, addr) -
I_MUL, // (dest, addr, addr) *
I_DIV, // (dest, addr, addr) /
} tInstCode;
typedef enum TypeI{
INT=0,
DOUBLE,
STRING
} TypeI;
typedef struct iOperand
{
TypeI type;
void *content;
} iOperand;
typedef struct tInst
{
tInstCode instType;
iOperand *op1;
iOperand *op2;
iOperand *res;
} tInst;
typedef struct ListItem
{
tInst Instruction;
struct ListItem *NextItem;
} tListItem;
my main file :
void generateInstruction(tInstCode instType, TypeI typ1, void *op1, TypeI typ2, void *op2, TypeI typ3, iOperand *op3 )
{
tListOfInstr list;
listInit(&list); //list defined in another file
tInst* I;
I->instType = instType;
I->op1->type = typ1;
I->op1->content = op1;
I->op2 -> type = typ2;
I->op2 -> content = op2;
I->res -> type = typ3;
I->res -> content = op3;
listInsertLast(&list, *I);
}
int main(int argc, char** argv)
{
int a;
a=8;
int *b;
b = &a;
int c;
c=1;
int *d;
d = &c;
generateInstruction(0, DOUBLE, *b, INT, *d, INT, NULL);
}
tInst* I;
I->instType = instType;
You're not allocating memory for I.
As it currently is I is just a pointer with a (potentially) random value. Use malloc to get a suitable address with free memory.
This could be done like this:
tInst* I;
I = malloc(sizeof(tInst));
I->op1 = malloc(sizeof(iOperand));
I->op2 = malloc(sizeof(iOperand));
I->res = malloc(sizeof(iOperand));
Though keep in mind that malloc can fail, so you want to check the return value for NULL.

Resources