I have any error with execute bad access for this program.
Firstly, I have 3 structure.
struct format {
int initialCyclicShift;
int nrOfSymbols;
int startingSymbolIndex;
int formatID;
};
struct PUCCH_Resource {
//38.331 maxNrofPUCCH-Resources = 128
int pucch_ResourceId;
int startingPRB;
int intraSLotFrequencyHopping;
int secondHopPRB;
// 5 formats in PUCCH, 38.211. Also in 38.331
struct format (*formatList)[5]; //(*formatList) is a pointer that points to the whole array of size 5. The element of the array is a struct format
};
struct PUCCH_ResourceSet {
// 38.331 maxNrOfPUCCH-ResourceSet=4
int pucch_ResoureSetId;
// 38.331 maxNrofPUCCH-ResourcePerSet = 32; for Initial Access: maxNrofPUCCH-ResourcePerSet = 16. There could be repetition of pucch resource in different sets.
struct PUCCH_Resource (*ResourceList)[32];
};
Then I initialize the pointer, pointing to the parents structures PUCCH_ResourceSet , and children structures.
struct PUCCH_ResourceSet *pucch_ResourceSetPtr = (struct PUCCH_ResourceSet*) malloc (sizeof(struct PUCCH_ResourceSet));
pucch_ResourceSetPtr->ResourceList = malloc(sizeof(struct PUCCH_Resource));
for (int i = 0; i <32; i++){
for (int j = 0; j <5; j++)
pucch_ResourceSetPtr->ResourceList[i]->formatList[j]= malloc(sizeof(struct format));
}
(edit) I tried to initialize all the structs as suggested by member below, but still have the same issue.
and then try a get function that assign value to each member of the struct, for example:
pucch_ResourceSetPtr->ResourceList[0]->pucch_ResourceId=0;
pucch_ResourceSetPtr->ResourceList[0]->startingPRB = 0;
pucch_ResourceSetPtr->ResourceList[0]->formatList[0]->formatID=0; //this is where I have the error
The line of code above is the first to assign a value to a member of struct; this is where I have the error.
Upon the bugging, I see that when the PUCCH_ResourceSet, it see a memory block is assigned to the struct, its child struct, PUCCH_Resource, but not its grandchildren struct, format as show in the screenshot below.
I suspect it is the issue, but dont understand why no memory block is assigned to the format struct.
In addition, after some manipulating of code in order to allocated memory to member of structs, I have a build error at the format struct:
Does any one know the reason for this behavior and how I can resolve it?
First in a nested structure, I have to allocate memory to the structure.
There are multiple issues in structure, that cause issue with the way I allocate memory. For example, I used pointer to any array instead of array of pointers.
struct format (*formatList)[5]; //this is no array of pointer but a pointer to the beginning of an array.
I should just use:
`struct format *formatList[5];`
For such, I couldn't allocate memory as I wanted in step 1 properly.
The suitable code for the declared structs are as below.
struct PUCCH_ResourceSet *pucch_ResourceSetPtr = (struct PUCCH_ResourceSet*) malloc (sizeof(struct PUCCH_ResourceSet));
printf("%d", sizeof(struct PUCCH_Resource*));
for (int i = 0; i <32; i++){
pucch_ResourceSetPtr->ResourceList[i] = malloc(sizeof(struct PUCCH_Resource));
for (int j =0; j <5 ; j++)
{
pucch_ResourceSetPtr->ResourceList[i]->formatList[j] = malloc(sizeof(struct format));
}
}
Related
I tried to create a struct that would incude a dynamic array:
typedef struct
{
int idNode;
int* n; //pointer to the int nodes in the dynamically created array of nodes
n = calloc(MAX, sizeof(int)); //dynamic array to store the loser member of the pair
int counter = 0;
}
node;
But I get
error: type name requires a specifier or qualifier
You cannot assign a value to n in the struct declaration. You need to provide a function (something like a constructor ;-) that initializes the structure and assigns a value to its members, including n:
void init_node(node* n)
{
n->idNode = ...;
n->n = calloc(MAX, sizeof(int));
n->counter = 0;
}
Note: you still need to handle errors (e.g. calloc may fail) in the function and propagate errors to its caller.
You can't have statements or initialize an variable inside a structures.
For fix your problem
typedef struct Node {
int idNode;
int* n; //pointer to the int nodes in the dynamically created array of nodes
int counter;
} node;
int main(void)
{
node data = null;
node.n = calloc(sizeof(int), MAX);
node.idNode = 0;
node.counter = 0;
return (0)
}
Now you have initialize your struct
Starting point
I tried to create a struct that would incude a dynamic array
The problem I see in your initial snippet is you mix definition, declaration and use.
From https://www.geeksforgeeks.org/difference-between-definition-and-declaration:
Declaration of a variable is for informing to the compiler the following information: name of the variable, type of value it holds and the initial value if any it takes. i.e., declaration gives details about the properties of a variable. Whereas, Definition of a variable says where the variable gets stored.
Steps to get a basic knowledge of how to do it.
Firstly, you must know how to create a struct.
The next step is how to typedef it.
The next step is how dynamic arrays are declarated, defined, created, stored, modified or destroyed (the life cycle). Pay attention to erros may occur during the execution. The happy path of create things in C is not the only one, there are plenty of errors out there!
The next step is how to insert them into a typedef'd struct.
And the last step is use that typedef struct with a dynamic array inside it. Even you can create multiple dynamic arrays in the struct!
Note: Steps, 1, 2 and 4 may be ordered in other ways depend on the programmer
There is no shortcuts, no trial and error and, of course, you must create test programs to ensure the stuff you want and the stuff you program are the same thing.
n = calloc(MAX, sizeof(int));
int counter = 0;
You cannot use statements to execute inside of the declaration of a structure. You need to initialize n and counter inside of a function after an object of node has been defined.
E.g.:
typedef struct
{
int idNode;
int* n;
int counter;
}
node;
int main (void)
{
node a;
a.n = calloc(MAX, sizeof(int));
a.counter = 0;
}
I just wanted to know if the following works. I have a struct
called foo that is defined as the following:
struct foo {
char name[255];
int amount;
};
During runtime, I need to create an array of the above structures whose size is dependent on a value I receive from a file's input. Let's say this size is k. Will the following code appropriately allocate a dynamically-sized array of structures?
struct foo *fooarray;
fooarray = malloc(k * sizeof(struct foo));
EDIT: If I want to access members of the structures within these arrays, will I use the format fooarray[someindex].member?
That will work (and your accessing is correct). Also, you can guard against size errors by using the idiom:
fooarray = malloc(k * sizeof *fooarray);
Consider using calloc if it would be nice for your items to start out with zero amounts and blank strings, instead of garbage.
However, this is not a VLA. It's a dynamically-allocated array. A VLA would be:
struct foo fooarray[k];
Yes it will.
On failure it will return 0.
And you have to free the memory returned by malloc when you are done with it
You can access the first member:
fooarray[0].name
fooarray[0].amount
The second as:
fooarray[1].name
fooarray[1].amount
etc..
One more different notation can be used in this approach:
struct foo {
char name[255];
int amount;
};
int main (void)
{
struct foo *fooarray;
struct foo *fooptr[5];
unsigned int i = 0;
for (i = 0; i < 5; i++)
fooptr[i] = malloc(1* sizeof(struct foo));
fooptr[2]->name[3] = 'A';
printf ("\nfooptr[2]->name[3]=%c\n",fooptr[2]->name[3]);
}
i have the following structure:
typedef struct Course {
int course_id;
char* course_name;
int prior_course_id;
StudentTree* students;
} Course;
and the following function i need to implement:
void createReport(FILE* courses[], int numOfCourses, FILE* studentFile, char* reportFileName
as you can see i get an array of FILE*, each cell contains different file pointer.
my intention is to create an array that each cell is Course* type, and initialize each cell with a Course struct containing the data read from the courses files.
what is the correct way to declare it inside the function?
do i need to dynamically allocate memory for it, or it can be done in compilation?
i've tried
Course* course_array[numOfCourses] = {NULL};
Course* course_array[numOfCourses] = NULL;
but it won't compile.
thanks for your help
You declare an array of structs the same way you declare an array of ints or FILE *s:
Type variableName[numberOfElements];
Before C99 (and barring compiler specific extensions), creating an array with a variable number of elements on the stack wasn't supported. So make sure that you are targeting the correct standard. In your case, assuming C99 support, the following should work:
Course *course_array[numOfCourses];
Because you intend to initialize each of the elements in the array, there is no need to zero them out.
You would then access the elements like this:
course_array[0] = malloc(sizeof(Course))
course_array[0]->course_id = 2;
/* etc. */
Now if you can't assume C99 support, things get a bit more tricky but not much:
Course *course_array = malloc(sizeof(Course *) * numOfCourses);
After that you can access course_array with the same array notation:
course_array[0] = malloc(sizeof(Course))
course_array[0]->course_id = 42;
/* etc. */
Once you're doing with the array, you'll need to make sure that you free any of the memory that you allocated:
for (i = 0; i < numOfCourses; i++) {
free(course_array[i]);
}
/* If you malloc'd course_array, then you need this too */
free(course_array);
Course* course_array[numOfCourses] = {NULL};
This is good, but it creates array of Course *. So you need to allocate memory for each pointer in course_array before accessing it.
Something like
course_array[0] = malloc(sizeof(Course));
course_array[0]->course_id = someid;
When you define the array in the first place, you shouldn't need to allocate memory. You're defining the array on the stack, and the elements of the array are just pointers.
I think what you should do is first define the array, and then initialize each element with a malloc call. For example:
Course* course_array[numOfCourses];
for(int i = 0; i < numOfCourses, i++) {
course_array[i] = (Course*)malloc(sizeof(Course));
My favorite way:
typedef struct {
int a;
char b;
float c;
}DATA;
//then use typdef'ed DATA to create array (and a pointer to same)
DATA data[10], *pData;
//then, in function, you can initialize the pointer to first element of array this way:
int main(void)
{
pData = &data[0];
return 0;
}
Your example code would look like this:
typedef struct {
int course_id;
char* course_name;
int prior_course_id;
StudentTree* students;
} COURSE;
//then in function:
COURSE course[numOfCourses]
I am working through Learn C The Hard Way and am stumped on something. I've written a simplified version of the problem I am running into to make it easier to get down to it:
#include <stdlib.h>
#define GROUP_SIZE 10
#define DATA_SIZE 64
struct Dummy {
char *name;
};
struct Group {
struct Dummy **dummies;
};
int main() {
struct Group *group1 = malloc(sizeof(struct Group));
group1->dummies = malloc(sizeof(struct Dummy) * GROUP_SIZE);
struct Dummy *dummy1 = group1->dummies[3];
// Why does this seg fault?
dummy1->name = (char *) malloc(DATA_SIZE);
return 0;
}
When I try to set the name pointer on one of my dummies I get a seg fault. Using valgrind it tells me this is uninitialized space. Why is this?
Your use of dummies appears inconsistent with its declaration. From the way you use the dummies field it appears that dummies was intended as an array of Dummy structs, not an array of arrays of Dummy structs. If this is the case, change your declaration to this:
struct Group {
struct Dummy *dummies; // Single asterisk
};
Then change your usage as follows:
struct Dummy *dummy1 = &group1->dummies[3];
Of course this assumes that GROUP_SIZE is four or more.
you never malloced space for the Dummy itself. You need to do something like:
group1->dummies = malloc(sizeof(Dummy *) * GROUP_SIZE);
for(int i = 0; i < GROUP_SIZE; i++) {
group1->dummies[i] = malloc(sizeof(struct Dummy));
}
struct counter{
long long counter;
}
struct instruction{
struct counter *counter
int repetitions;
void (*work_fn)(long long *);
};
int ncounter; //number of counters
struct counter *counter; //counter array
int nthreads; //number of threads
int *ninstructions; //number of instructions
struct instruction **instructions;
How does this actually works ? I am having trouble with ** pointers
A ** is just a pointer to a pointer. So where an instruction* contains the address of an instruction struct, an instruction** contains the address of an instruction* that contains the address of an instruction object.
To access the instruction pointed to by the pointer pointed to by an instruction**, you just use two asterisks instead of one, like (**p).repetitions or something similar.
You can visualize it like this:
instruction* ----> instruction
instruction** ----> instruction* ----> instruction
Remember, however, that simply declaring struct instruction** instructions; doesn't actually create an instruction struct. It just creates a pointer that holds a garbage value. You'll have to initialize it:
struct instruction inst;
// set members of inst...
*instructions = &inst;
...
(*instructions)->repetitions++; // or whatever
However, it looks like you're using an instruction** to point to an array of instruction*s. To initialize the array, you need a for loop:
instructions = malloc(sizeof(struct instruction*) * num_of_arrays);
for (i = 0; i < num_of_arrays; ++i)
instructions[i] = malloc(sizeof(struct instruction) * size_of_each_subarray);
And then you can access an element like instructions[i]->datamember.
struct instruction **instructions; // How does this actually works ? I am having trouble with ** pointers
I'm not sure what the real issue is, but I'll try to answer the question.
Double pointer is a pointer to pointer. It can be sued as array of pointers for example (if you allocate memory accordingly). For example:
instructions = malloc(5*sizeof(struct instruction*));
for (int i = 0; i < 5; i++)
instructions[i] = malloc(sizeof(struct instruction));
And you got yourself nice array of 5 pointers to struct instruction. Use it like this:
instructions[0]->repetitions = 0;
instructions is a pointer to a pointer to struct instruction.
This means that *instructions will give you a pointer to a struct instruction. This kind of construct is often used to create a dynamic array of pointers to some compound type.