I have a struct like this:
struct students {
char *names[MAXLENGTH];
};
How would I initialize the struct using malloc?
I tried
struct students student1 = {malloc(MAXLENGTH * sizeof(char**))};
but that gave me a "missing braces around initializer" error.
I'm new to C, so I'm not sure how to fix this.
You can allocate an instance of the struct like this:
struct students *pStudent = malloc(sizeof *pStudent);
This will allocate the array of string pointers (since it's part of the struct students), but not set the pointers to point at anything (their values will be undefined).
You need to set each individual string pointer, for instance like so:
pStudent->names[0] = "unwind";
This stores a pointer to a literal string. You can also allocate memory dynamically:
pStudent->names[1] = malloc(20);
strcpy(pStudent->names[1], "unwind");
of course, if you malloc() space you must remember to free() it. Don't mix literal strings with dynamically allocated ones, since it becomes impossible to know which ones need free()ing.
This is totally wrong struct students student1 = {malloc(MAXLENGTH * sizeof(char**))};
Try this code.
struct students* Student1 = malloc(sizeof(struct students ));
Student1->names[0] = malloc(sizeof(NAME_MAX));
scanf("%s",Student1->names[0]);//It may be first name. I think you want like this .
You have to use a for loop like this :
#define MAX_NAME_LENGTH 20
struct student s;
for(int i = 0; i < MAXLENGTH; ++i)
{
s.names[i] = malloc(sizeof(char) * MAX_NAME_LENGTH);
}
Related
if i have a simple struct such as
How would i got about dynamically allocating memory for this struct using malloc?
struct Dimensions{
int height, width;
char name;
};
I um unsure on how to go about this, I have tried
struct Dimension* dim = malloc(sizeof(struct Dimensions));
Also I would like then access the height and width variable in a loop later on in my code. My first thought would be to use a pointer but im unsure on what this would exactly be.
Would it be something like
int h = *width
I'm very new to C. Thanks
The way you dynamically allocated that struct is correct:
struct Dimension* dim = malloc(sizeof(struct Dimensions));
Also I would like then access the height and width variable in a loop later on in my code.
You should first assign some value to that dim first, something like:
dim->high = 1;
dim->width = 2;
The name member you just used a char which might not be what you need. Usually it's a string: char name[100];. You can't use assignment for that string though, so use strcpy.
Then you can access that later:
int h = dim->high;
Remember once you're done with the dynamically allocated memory, you should free it:
free(dim);
return 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]
hi i have this structure
typedef struct STUDENT
{
char studName[20];
int timeEnter;
int timeUpdate;
}STUDENT;
and the local pointer to array of structure
STUDENT *studArr[100];
I'm trying to allocate memory for the structure by doing reading in the first line of the file then use it to allocate memory for the structure.
fscanf(fp, "%s", &first);
**studArr = (STUDENT**) malloc(sizeof(STUDENT*)*first);
I got an error saying that no operator "=" matches these operands on the allocation line
why am I gettting the error, what did i do wrong here?
thank in advance
I think you're confusing things, it looks like you're declaring an array of pointers, when all you need is a single pointer. Note that as long as you're indexing properly, a pointer to "one" struct is the same as a pointer to a hundred.
You should probably have:
STUDENT *studArr;
then, once you know how many you need (I'm assuming first is the number of students to allocate room for):
studArr = malloc(first * sizeof *studArr);
Also note that no casting is needed.
If you want to allocate an array of 100 students, you have two choices:
struct STUDENT
{
char studName[20];
int timeEnter;
int timeUpdate;
};
struct STUDENT studArr1[100];
... OR ...
struct STUDENT *studArr2 = (struct STUDENT *)malloc (sizeof (struct STUDENT) * 100);
If you just want a pointer, you can say:
struct STUDENT *p = studArr1;
PS:
I deliberately left the "typedef" stuff out so as not to confuse the basic issue (struct vs. array of struct vs pointer to array of struct).
You have defined an array of pointers to struct, not a pointer to an array of struct. The memory for the array is already allocated, as a global array.
The type of **studArr is STUDENT, and hence is not compatible with the expression to the right of the assignment operator, which is casted to (STUDENT**).
You probably meant:
STUDENT **studArr;
[...]
fscanf(fp, "%s", &first);
studArr = (STUDENT**) malloc(sizeof(STUDENT*)*first);
As you are using STUDENT *studArr[100]; then it means you have allocated the memory for 100 pointers for STUDENT structure type.
so for allocating the memory you should try.
studArr =malloc(sizeof(struct STUDENT)*first);
then you can access all the allocated members as studArr[i] ....so on.
You're not exactly clear on what your overall goal is.
First of all, you want to use %d if you want to read in an integer:
int count;
if (fscanf(fp, "%d", &count) != 1) { // error... }
Next, don't use STUDENT as both the struct name and the typdef. Just leave the struct name out:
typedef struct
{
char studName[20];
int timeEnter;
int timeUpdate;
} student_t;
Now, you're going to want just a pointer to an array of student_ts:
student_t* student_array = NULL;
Finally, allocate that array:
student_array = malloc(count * sizeof(student_t));
Now you can use it, like:
strncpy(student_array[0].studName, "Bobby", 20);
Or get a pointer to an individual student:
student_t* bob = &student_array[1];
bob->timeEnter = 42;
I am a newbie in C..I am trying to make some sense of how dynamic memory allocation works in case of structures and arrays..So like for example I have a code like..
struct Person
{
int id;
char *name;
char *place;
};
struct Database
{
struct Person *data_rows;
};
I want to dynamically allocate memory for both the character arrays name and place..and the array of struct data_rows..take their size as input..So what should ideally be the order of allocations and the proper syntax for the same? Thanks.
Well, "obviously" you need to get "struct Database" filled in first:
struct Database MyDatabase;
MyDatabase.data_rows=malloc(sizeof(MyDatabase.data_rows[0])*NumberOfPeople);
Ignoring the fact that I didn't check the malloc() for failure, this will give you an array of "struct Person", all uninitialized. So, most likely, you'll want to initialize them:
int i;
for (i=0; i<NumberOfPeople; i++)
{
struct Person* MyPerson;
MyPerson=&MyDatabase.data_rows[i];
MyPerson->id=i;
MyPerson->name=malloc(...);
/* Do something to store the name in MyPerson->name */
MyPerson->place=malloc(...);
/* Do something to store the place in MyPerson->name */
}
Now, the problem here is the "..." I put on the malloc. It's easy if you use a fixed size, but then you could have just declared your struct to be something like
struct Person
{
int id;
char name[100];
char place[200];
};
Basically, I just can't tell what the length of the names should be, hence I just typed it as "...".
Also, I just guessed what the "id" might be. Using the array index is actually somewhat pointless :-)
Of course, you don't have to do it all now. You could just set the name and place pointers to NULL and fill them in later, like when you're reading the data from a file, or whatever you're planning to do. Or you could just not initialize it here at all, if you're confident that your code always "knows" which fields are initialized and which ones are not.
I would highly recommend to write a functions person_new and person_free that would take care of structure memory management:
struct Person* person_new(char *name, char* place) {
struct Person* person = malloc(sizeof(struct Person));
person->name = strdup(name);
person->place = strdup(place);
return person;
}
void person_free(struct Person* person) {
free(person->name);
free(person->place);
free(person);
}
The best thing would be to convert your structs to classes, the following works also for structs...
You define a constructor and destructor in Database and in Person as following:
struct Person
{
Person(){
name = new char[256];
place = new char[256];
};
~Person(){
delete name;
delete place;
}
int id;
char *name;
char *place;
};
struct Database
{
Database(int nPersons){
data_rows = new Person[nPersons];
};
~Database(){
delete data_rows;
};
struct Person *data_rows;
};
or you can do this without a constructor and destructor and allocate all the stuff sequentially in your code, which is a very ugly way to do this!
as:
Database myData;
myData.data_rows = new Persons[40];
for(int i=0; i < 40; i++){
myData.data_rows[i].name = new char[256];
myData.data_rows[i].place = new char[256];
}
Note that data_rows[i] is nothing more than -> *(data_rows + i) which shifts the address of the pointer i times and then dereferences it!