Struct memory allocation fault - c

I am writing a C project with pointers and structs, and right now facing this problem:
There is a structure
struct Customer
{
char Name[80];
char Address[40];
int ID;
int Pnumber;
};
and I am gonna make a dynamic array of this structs with *line_count* number of members. I use this code, but it crashes a program:
struct Customer* ph;
ph = (struct Customer*)malloc(line_count * sizeof(struct Customer));
What am I doing wrong?

Good:
struct Customer* ph;
ph = (struct Customer*)malloc(line_count * sizeof(struct Customer));
Better:
struct Customer* ph =
(struct Customer*)malloc(line_count * sizeof(struct Customer));
if (!ph) {
<<error handling>>
...
But frankly, it sounds like the problem is elsewhere in your code.
There's nothing fundamentally wrong with your malloc().
Maybe "line_count" is bogus, maybe "malloc()" is failing (in which case, it should return "NULL") ... or maybe you're accessing the struct incorrectly and/or failing to initialize it correctly.
A stack traceback of the actual crash would be very useful.

The piece of code you are showing might crash only if ph == NULL after the malloc call and you dereference it.
From the malloc man page:
The malloc() and calloc() functions return a pointer to the allocated
memory that is suitably aligned for any kind of variable. On error,
these functions return NULL. NULL may also be returned by a
successful call to malloc() with a size of zero, or by a successful
call to calloc() with nmemb or size equal to zero.

Related

Structures and dynamic memory in C

I'm a beginner in C.
I want to assign each person's info to an array of pointer that is *arr[2]
but I get an error message that is
'malloc' is not declared in this scope.
How can I fix it?
#include <stdio.h>
int main()
{
struct person {
char *name;
int number;
char gender;
};
struct person *arr[2];
arr[0] = (struct person *) malloc(sizeof(struct person));
arr[0]->name = "john";
arr[0]->number = 123;
arr[0]->gender ='m';
arr[1] = (struct person *) malloc(sizeof(struct person));
arr[1]->name = "jessica";
arr[1]->number = 456;
arr[1]->gender ='w';
printf("%s", arr[1]->name);
return 0;
}
A few inputs than just one.
Primarily:
The man page for malloc says that you need to include the header file: stdlib.h
#include <stdlib.h>
The one habit which would save you a lot of pain going ahead is to check if malloc() was successful or not. You must check the value returned by malloc().
arr[0] = malloc(sizeof(struct person));
if(arr[0] == NULL)
{
// Since malloc has returned NULL, requested memory is not allocated
// Accessing it is out of question
// Some error handling implementation
return;
}
Additionally, we should always return what we borrow, unless we don't crash all of sudden. Allocated memory needs to be freed. There are several examples on internet on how to de-allocate the dynamically allocated memory. A good start would be reading concepts like Memory Leakage and Dangling pointers.
The other suggestion would be:
If you look at the same (or the other) man page for malloc, you'd find that malloc returns a void pointer. So, you do not have to cast the malloc() result. There is this legendary post and a legendary answer which explains why not to cast.
You should include a header which defines malloc(). Usually, this would be stdlib.h.
You can use online help from cppreference.com or similar sites to get this information, and full documentation for the c libraries.
To actually use the function malloc,you should include the #include library which declares among other things the malloc(), calloc(), free() functions.

Understanding dynamic memory allocation of a string within a struct

I have come across an instance where memory is allocated dynamically to a char pointer within a struct in a way that does not make much sense to me, but - of course - works.
A similar question has been posted before. The answers, however, did not help me understand what is actually happening in the allocation process.
Here is the code example I found:
struct a_structure {
char *str;
struct a_structure *next;
};
Memory has been allocated in the following way:
ptr_start=(struct a_structure *)malloc(sizeof (struct a_structure *));
...
char *some_words="How does this work?";
ptr_start->str=(char *)malloc(strlen(some_words)+1);
strcpy(ptr_start->str, some_words);
ptr_start->next=(struct a_structure *)malloc(sizeof(struct a_structure *));
...
I don't understand why malloc is used with the size of a pointer here. ptr_start is a pointer of type struct a_structure. That would mean it needs memory of size sizeof(struct a_structure) + the size of my string that hasn't been specified in the structure declaration. In the above example, however, malloc returns the address of yet another pointer pointing to a structure of type a_structure, am I right?
I don't understand why malloc is used with the size of a pointer here.
ptr_start is a pointer of type struct a_structure. That would mean it
needs memory of size sizeof(struct a_structure) + the size of my
string that hasn't been specified in the structure declaration
You are right. To create structure a_structure in order to manipulate it we need to allocate memory for whole structure.
(Unless the object has been ALREADY created and for whatever reason we need a dynamically allocated pointer holding pointer to that object).
but - of course - works.
The presented fragment of the program cannot work properly for the stated above reasons.
In the above example, however, malloc returns the address of yet
another pointer pointing to a structure of type a_structure, am I
right?
Yes, you are right.
This is also problematic:
ptr_start->next=(struct a_structure *)malloc(sizeof(struct a_structure *));
ptr_start->next can hold a pointer already. We typically do not need to allocate a pointer here. We would assign a pointer to the existing
structure or we would allocate memory for the whole structure.
See example:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct a_structure {
char *str;
struct a_structure *next;
};
struct a_structure * allocatePointer(void)
{
// ptr ptrToObj1Allocated points to allocted memory which can hold a ponter
struct a_structure * ptrToObj1Allocated = malloc(sizeof (struct a_structure *));
return ptrToObj1Allocated;
}
int main(){
// 1.
struct a_structure obj1; // structure a_structure has been allocated on the stack
struct a_structure * ptrToObj1 = & obj1; // points to the existing structure
char *some_words = "How does this work?";
ptrToObj1->str = malloc(strlen(some_words)+1);
if(ptrToObj1->str == NULL){printf("No enough memory\n"); return -1;}
strcpy(ptrToObj1->str, some_words); // copy the string
// now obj1 has its own copy of the string.
// 2.
// dynamically allocate another structure on the heap
// we want to allocate memory for the structure not just a memory to keep the pointer to the structure.
struct a_structure *obj2 = malloc( sizeof (struct a_structure)); // memory has been allocated to hold struct a_structure with 2 pointers
if(obj2 == NULL){printf("No enough memory\n"); return -2;}
char *words = "More words..";
obj2->str = malloc(strlen(words)+1);
if(obj2->str == NULL){printf("No enough memory\n"); return -3;}
strcpy(obj2->str, words); // copy the string
obj2->next = ptrToObj1; // points to the already existing object
//----
printf("String in obj1 is: %s\n", ptrToObj1->str);
printf("String in obj2 is: %s\n", obj2->str);
printf("obj2->next points to structure with string: %s\n", obj2->next->str );
// free the allocated memory:
free(ptrToObj1->str);
free(obj2->str);
free(obj2);
return 0;
}
Output:
String in obj1 is: How does this work?
String in obj2 is: More words..
obj2->next points to structure with string: How does this work?
Given that you have struct a_structure* ptr_start, this code is incorrect and does not work:
ptr_start=(struct a_structure *)malloc(sizeof (struct a_structure *));
It should have been:
ptr_start = malloc(sizeof *ptr_start);
The reason why it "seems to work" is because you invoked undefined behavior, and anything can happen. The program could seem to work one moment, then crash at another time.
This does however just allocate the struct itself. The pointers inside it will, like all pointers, point at memory allocated somewhere else. The following code with malloc for the string and strcpy() is one way to do so.
The last line is however incorrect for the same reason as pointed out above.

How to allocate memory to struct pointer using malloc.h header?

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct student
{
char name[25];
int age;
};
int main()
{
struct student *c;
*c =(struct student)malloc(sizeof(struct student));
return 0;
}
What is the wrong with this code? I tried times by alternating this code to allocate memory to struct pointer. But this error comes when compiling:
testp.c:15:43: error: conversion to non-scalar type requested
*c =(struct student)malloc(sizeof(struct student));
^
I'm using mingw32 gcc compiler.
What is the wrong with this code?
Ans: First of all you change that "is" to "are", there are two major problems, atleast. Let me elaborate.
Point 1. You allocate memory to the pointer, not to the value of pointer. FWIW, using *c (i.e., de-referencing the pointer without memory allocation) is invalid and will result in undefined behaviour.
Point 2. Please do not cast the return value of malloc() and family in C. The cast you used is absolutely wrong and proves the authenticity of the first sentence.
To solve the issues, change
*c =(struct student)malloc(sizeof(struct student));
to
c = malloc(sizeof(struct student));
or, for better,
c = malloc(sizeof*c); //yes, this is not a multiplication
//and sizeof is not a function, it's an operator
Also, please note, to make use of malloc() and family , you don't need the malloc.h header file. These functions are prototyped in stdlib.h.
EDIT:
Suggestions:
Check for success of malloc() before using the returned pointer.
Always free() the memory once the usage is over.
The recommended signature of main() is int main(void).
This worked (on C and C++).
Since you originally included both tags.
change
*c =(struct student)malloc(sizeof(struct student));
to
c =(struct student*) malloc(sizeof(struct student));

Segmentation Fault in a struct with a pointer to another struct

I'm having some issues with my linked list. I have struct dListNode used as the nodes for the list with a pointer to struct data, which is used as the data storage.
struct data{
int payload;
};
struct dListNode{
struct dListNode *next;
struct dListNode *prev;
struct data *val;
}*dHead, *dTail;
My program compiles fine, but I get a segmentation fault at the line indicated below. What is going on?
newDNode = (struct dListNode *)malloc(sizeof(struct dListNode)+sizeof(struct data));
printf("newnode created\n"); // this prints
newDNode->val->payload = rand() % 1000; //error here?
printf("newnode payload: %i\n", newDNode->val->payload); //seg fault before this is printed
Also, I have already ran this line in the program: srand((unsigned)time(NULL))
NewDNode doesn't have an associated memory allocation to it. So when you do
newDNode = (struct dListNode *)malloc(sizeof(struct dListNode)+sizeof(struct data));
This just allocates memory to newDnode and not to newDnode->val. Since newDNode->val just contains whatever was leftover in the memory at that location (or maybe even 0 (NULL pointer)), and you try to assign a value to the memory location which is neither on the stack nor on the heap, the program complains because you are trying to access unassigned part of memory.
Here's what you should do:
newDNode = malloc(sizeof(struct dListNode));
newDnode->val = malloc(sizeof(struct data));
printf("newnode created\n");
newDNode->val->payload = rand() % 1000;
printf("newnode payload: %i\n", newDNode->val->payload);
And as a tip, always try to not cast the result returned by malloc (or any other memory allocation function). Its considered bad practice.
You problem is that you never initialized the pointer val:
newDNode->val->payload = rand() % 1000;
newDNode is allocated, but none of the fields are initialized, so dereferencing val will likely cause that segmentation fault.
So you will need to allocate something for val before you access it.
newDNode = malloc(sizeof(struct dListNode)); // Allocate "dListNode"
newDNode->val = malloc(sizeof(struct data)); // Allocate "data"
newDNode->val->payload = rand() % 1000;
You have a slight misunderstanding of how the allocation works. You need to allocate each pointer separately.
EDIT : And alternate approach is just to not use a pointer for val in the first place:
// Declare struct as:
struct dListNode{
struct dListNode *next;
struct dListNode *prev;
struct data val;
}*dHead, *dTail;
// Build object like this:
newDNode = malloc(sizeof(struct dListNode));
newDNode->val.payload = rand() % 1000;
val does not point to a valid data structure. Sure, you malloc enough size, but that doesn't mean that val is now all of a sudden a valid pointer. You should initialize newDNode with just the size of a dListNode and then separately initialize newDNode->val to point to some valid chunk of memory large enough for a data structure.
On a side note, you don't need to cast the return value of malloc. That's a C++ thing; in C a void* can be implicitly converted to any other pointer type.
Second, if you typedef your struct types you don't have to write struct all over the place when using them.
You're never setting newDNode->val to point to anything. So when you try to set newDNode->val->payload, you're dereferencing either a null pointer or some random address (i forget which). Neither case is what you want.
I don't really like the idea of malloc'ing both the structs in the same statement. But if you insist on doing it, you'll need to do something like
newDNode->val = (struct data*)((char*) newDNode + sizeof(struct dListNode));
A better way, though, is to change the struct so that val is a struct rather than just a pointer to one. Then sizeof(struct dListNode) includes the size of struct data, and you can access it like newDListNode->val.payload without having to malloc the data part separately or do any tricky pointer math. (Drawback being, you'd have to copy the structs to store them in an array, swap them around, etc.)

Am i using malloc properly?

Good day!
I need to use malloc in creating a student list system.... In order to be efficient, our professor asked us to use it on a struct so i created a struct as follows:
struct student {
char studentID[6];
char name[31];
char course [6];
};
struct student *array[30];
everytime i add a record, that is when i use malloc...
array[recordCtr]=(struct student*)malloc(sizeof(struct student));
recordCtr++;
then i free it like this.
for(i = 0; i < recordCtr; i++){
free(array[i]);
}
Am i using malloc properly??? what is the effect if i free it like this instead of the loop above.
free(array);
Thanks in advance. Your opinion will be highly appreciated.
You are doing fine.
free(array); would be undefined behavior because array itself was not allocated via malloc therefore you can't free it and don't need to - the memory will be managed by the compiler.
A good tip is to always do:
type *something;
something = malloc(n * sizeof(*something));
This is because, if you change the type of something, you don't have to change all sorts of other code. And sizeof is really a compiler operation here, it won't turn into anything different at runtime.
Also, don't cast the void* pointer returned by malloc, there's no reason to do so in C and it just further ties your code together.
So in your case, don't do:
(struct student*)malloc(sizeof(struct student));
but
malloc(sizeof(**array));
There is nothing illegal about the way you are using malloc but this isn't a list, it's an array of pointers.
To use a list you do not fix the size in advance and have a pointer to the next element. You can either make this intrusive of non-intrusive.
For an intrusive list you put struct student * next in the declaration of student.
For a non-intrusive list you create another struct student_list_node which contains an instance of struct student and a pointer struct student_list_node * next;
This is an exacmple of the non-intrusive version:
struct student_list_node
{
struct student data;
struct student_list_node * next;
};
struct student_list_node * head;
struct student_list_node * tail;
struct student_list_node * addStudentToTail()
{
struct student_list_node * newnode = (struct student_list_node *)(malloc( sizeof(struct student_list_node ) );
/* check malloc did not fail or use a checking vesrion of malloc */
if( !tail )
{
head = tail = newnode;
}
else
{
tail->next = newnode;
tail = newnode;
}
return newnode; // which is also "tail"
}
int main()
{
struct student_list_node * node = addStudentToTail();
struct student * pstud = &node->data;
/* write to pstud student details */
}
If you do really want to use an array, you might want to make it an array of student rather than student * in which case you can use calloc rather than malloc
struct student * array = (struct student *)calloc( 30, sizeof( student ) );
Then using free(array) would be the correct way to dispose of it. You also have the option of allocating more if you need it later with realloc. (Be careful with this one: you must keep a copy of your original pointer until you know realloc succeeds).
The array itself isn't allocated on the heap. Assuming it's a global variable, it is allocated in global memory at program startup and doesn't need to be freed. Calling free on it will probably corrupt your program.
Your current solution is correct.
What you're doing is correct.
You can think of *array[30] as an array of 30 pointers
When you are allocating memory for each of those pointers, you'd also need to call free() on each of them.
Yes, you are using it correctly. There are better ways to organize the storage than this, but this will work. At least until you need more than 30 students...
Note that you must call free() with each pointer that is returned by malloc(). That means that your loop over the array of pointers is the correct approach for your chosen architecture.
Your attempt to call free on the array itself will not work. It invokes Undefined Behavior because you are passing a pointer (to the base of the array itself) to free() that did not come from a call to malloc().
Looks fine.
You could (if it fits your problem) allocate space for all 30 structs in one go
struct student *array = (struct student *)malloc(30*sizeof(struct student));
whhen you want to dispose of the space, you can then do
free(array)
What you have will work just fine. As others have mentioned, you've created an array of pointers on the stack and need to malloc and free each of them individually as you are doing.
However, you don't have to use malloc and free one struct at a time, you can do something like this:
int arraySize = 30;
student * ourArray = (student*)malloc(sizeof(student) * arraySize);
and a single free on the pointer will take care of it. with this pointer, you can still use the bracket notation and the compiler will understand that it's a typed pointer and behave appropriately, giving you essentially the same thing. Which method you use depends on if you need your array a dynamic size or not as well as personal preference.
Hope that helps some.
Initialize your array of pointer to struct student with NULL values
for(i = 0; i < recordCtr; i++){
array[i] = NULL;
}
Free memory if array[i] is not NULL
for(i = 0; i < recordCtr; i++){
if(NULL != array[i])
{
free(array[i]);
}
}
There's simple rule: Every malloc() should be paired with free() with pointer returned by malloc. Not less, not more.

Resources