I am new to programming and have just learned C shortly. Now my problem is, i tried to malloc a struct array, and then use it to fill in some information. but keep getting the heap overflow error report.
here is my declaration of struct in the h.file.
typedef struct llnode {
char llnodename[256];
int ll_index;
struct llnode* next;
} llnode;
//the struct of a linked list.
typedef struct node_stru {
char nodename[256];
int node_index;
} node_stru;
//the struct of the node.
and the pointer:
node_stru *node_list = (struct node_stru*)malloc(n_nodenumber*(sizeof(node_stru)));
but later when i wants to use the linked list to fill in some information,it give me the heap overflow.
llnode* ptr=Ahead;
while (ptr!=NULL){
printf("the name%s, the index%d", ptr->llnodename, ptr->ll_index);
strcpy(node_list[n_index].nodename, ptr->llnodename);
node_list[n_index].node_index = ptr->ll_index;
n_index++;
ptr = ptr->next;
}
The error report: I do malloc a 4*(256+4) memory, but it still not working.
0x619000000490 is located 0 bytes to the right of 1040-byte region [0x619000000080,0x619000000490)
You've allocated a fixed size for node_list, but there's nothing stopping your loop from walking off the end. For example, if n_nodenumber is 4 you can store 4 nodes. But if Ahead is linked to 5 nodes it will walk off node_list. That's assuming n_index starts at 0.
At minimum your loop should assert(n_index < n_nodenumber) to provide a better error when the loop walks off the array. That's all I can say without seeing a complete example.
Related
I am getting a segmentation fault whenever I try to print the value stored within a struct. Using Valgrind, I was able to narrow it down a bit to one block of code, but I am unsure what I am doing wrong. Am I initializing my struct incorrectly?
Whenever I run valgrind, it tells me that there is an invalid write of size 8 where I say newList->data = d.
typedef struct List {
struct List *np[Ends]; // next/prev neighbors
Data data;
} *List;
typedef void *Data;
static void put(Data d) {
List newList = malloc(sizeof(List));
newList->data = d;
}
This is an example of why it's bad practice to typedef a pointer.
Because List is defined as an alias for struct List *, sizeof(List) gives you the size of a pointer, not the size of the struct. As a result, you're not allocating enough memory.
You instead want either malloc(sizeof(struct List)) or (preferably) malloc(sizeof *newlist)
I was looking into some memory management (pool + malloc + free) implementations using linked list, and I found that in most of them each node is something like this:
typedef struct node{
int usedSize;
node* next;
char mem[100];
}
and then the free(ptr) must be:
free(void* ptr){
node* item = (node*)((char*)ptr - sizeof(node*) - sizeof(int));
\\some code to put the "item" back to the pool
}
My question is this:
why shouldn't we put the char mem[100]; in the beginning of the structure to avoid the "pointer manipulation"?
the result is:
typedef struct node{
char mem[100]; // moved to the beginning
int usedSize;
node* next;
}
and then the free(ptr) is simpler:
free(void* ptr){
node* item = (node*)((char*)ptr);
\\some code to put "item" back to the pool
}
Thanks.
That pointer manipulation is not particularly complicated. It amounts to a decrement by a compile time constant. As noted in comments, it should actually be:
node* item = (node*)((char*)ptr - offsetof(struct node, mem));
Placing that header above the memory allows the memory to be represented by a flexible array member. A flexible array member can only occupy the last position of a structure. This was also noted in comments.
typedef struct node {
int usedSize;
node* next;
char mem[];
} node;
If the size of the memory is large, jumping over the array to reach the next pointer will likely flush data cache lines to load the bookkeeping data. However, a short jump backward from the array will likely access the data already loaded into the cache.
I got stuck when trying to remove even number from queue in C programming. Here is the code:
My data structure for Queue:
typedef struct _listnode
{
int data;
struct _listnode *next;
} ListNode; // You should not change the definition of ListNode
typedef struct _linkedlist
{
int size;
ListNode *first;
} LinkedList; // You should not change the definition of LinkedList
typedef struct _queue
{
LinkedList list;
} Queue;
And I am calling from my main:
case 3:
deleteEven(&q); // You need to code this function
printf("Result:\n");
printList(&q.list);
break;
What I am trying to do is first, I tried to check if the queue is empty. Then I will get the linked list head and modulus with 2, if getting 0 means it's even number and then I will dequeue it from the queue.
However, with these code, when I try to dequeue even numbers from queue, it just stopped working and not showing any error message.
Anybody know how to solve this? Thanks in advance.
In your function deleteEven's while loop you do this -
free(odd->list.first->data); //problem 1
odd->list.first->data= odd->list.first->next; //problem 2- assigning pointer type to int
Problem 1- But you haven't allocated memory to odd->list.first->data , it is an integer variable. And if you try to free such thing can cause error in your program (you should not free memory not allocated by malloc or similar functions)
You allocate memory to odd , so free pointer odd.
Even you should not free inside your while loop, as you allocate memory only one time .
Problem 2 - You assign pointer type to int. That's may also be one of reason for this error .
You should write loop like this -
while (!isEmptyQueue(odd)) {
enqueue(que, odd->list.first->data);
odd->list.first= odd->list.first->next; // increment pointer
}
free(odd);
3. While calling function dequeue -
dequeue(que->list.first->data);
int is passed but it expects Queue * .
Its type is int but you return NULL from it (return -1 or something to show failure).
So I'm doing some linked list revison and Im trying to just load a list with some numbers and then print it out. Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack {
int data;
struct stack *next;
}*stack;
stack create_s(void){
stack s = (void*)malloc(sizeof(stack));
s->next = NULL;
return s;
}
void push_s(stack s, int data) {
while (s->next != NULL) {
s = s->next;
}
s->next = (void*)malloc(sizeof(stack));
s=s->next;
s->data = data;
s->next = NULL;
}
void print_s(stack s) {
if (s==NULL) {
return;
}
else {
while (s->next != NULL) {
printf("%d\n",s->data);
s=s->next;
}
}
}
int main (void) {
stack s = create_s();
push_s(s,2);
push_s(s,4);
push_s(s,6);
push_s(s,8);
print_s(s);
return 0;
}
My output is however:
-1853045587
2
4
6
when it should be
2
4
6
8
Is it printing the address of my struct at the beginning? Also, why is it not printing my last element?
Thanks
The code contains several errors, but the first thing that catches the eye is that your memory allocation is already obviously broken
stack s = (void*)malloc(sizeof(stack));
You defined stack as a pointer type. This means that sizeof(stack) evaluates to pointer size and the above malloc allocates enough space to store a single pointer, not enough for the entire struct stack object. The same memory allocation error is present in push_s as well.
Here's some advice
Don't hide pointer types behind typedef names. Define your stack as
typedef struct stack{
int data;
struct stack *next;
} stack;
and use stack * wherever you need a pointer. I.e. make that * visible instead of hiding it "inside" a typedef name. This will make your code easier to read.
Don't cast the result of malloc. Anyway, what is the point of casting it to void * when it is void * already???
Don't use sizeof with types unless you really really have to. Prefer to use sizeof with expressions. Learn to use the following malloc idiom
T *p = malloc(sizeof *p);
or, in your case
struct stack *s = malloc(sizeof *s);
This will allocate a memory block of appropriate size.
Also, as #WhozCraig noted in the comments, the very first node in your list is apparently supposed to serve as a "sentinel" head node (with undefined data value). In your code you never initialize the data value in that head node. Yet in your print_s function you attempt to print data value from the head node. No wonder you get garbage (-1853045587) as the first line in your output. Don't print the very first node. Skip it, if it really is supposed to serve as a sentinel.
Also, the cycle termination condition in print_s looks strange
while (s->next != NULL)
Why are you checking s->next for NULL instead of checking s itself? This condition will terminate the cycle prematurely, without attempting to print the very last node in the list. This is the reason why you don't see the last element (8) in your output.
The actual cause of the given output can be fixed by changing:
s=s->next;
s->data = data;
to
s->data = data;
s=s->next;
I'm just reading about malloc() in C.
The Wikipedia article provides an example, however it justs allocate enough memory for an array of 10 ints in comparison with int array[10]. Not very useful.
When would you decided to use malloc() over C handling the memory for you?
Dynamic data structures (lists, trees, etc.) use malloc to allocate their nodes on the heap. For example:
/* A singly-linked list node, holding data and pointer to next node */
struct slnode_t
{
struct slnode_t* next;
int data;
};
typedef struct slnode_t slnode;
/* Allocate a new node with the given data and next pointer */
slnode* sl_new_node(int data, slnode* next)
{
slnode* node = malloc(sizeof *node);
node->data = data;
node->next = next;
return node;
}
/* Insert the given data at the front of the list specified by a
** pointer to the head node
*/
void sl_insert_front(slnode** head, int data)
{
slnode* node = sl_new_node(data, *head);
*head = node;
}
Consider how new data is added to the list with sl_insert_front. You need to create a node that will hold the data and the pointer to the next node in the list. Where are you going to create it?
Maybe on the stack! - NO - where will that stack space be allocated? In which function? What happens to it when the function exits?
Maybe in static memory! - NO - you'll then have to know in advance how many list nodes you have because static memory is pre-allocated when the program loads.
On the heap? YES - because there you have all the required flexibility.
malloc is used in C to allocate stuff on the heap - memory space that can grow and shrink dynamically at runtime, and the ownership of which is completely under the programmer's control. There are many more examples where this is useful, but the one I'm showing here is a representative one. Eventually, in complex C programs you'll find that most of the program's data is on the heap, accessible through pointers. A correct program always knows which pointer "owns" the data and will carefully clean-up the allocated memory when it's no longer needed.
What if you don't know the size of the array when you write your program ?
As an example, we could imagine you want to load an image. At first you don't know its size, so you will have to read the size from the file, allocate a buffer with this size and then read the file in that buffer. Obviously you could not have use a static size array.
EDIT:
Another point is: When you use dynamic allocation, memory is allocated on the heap while arrays are allocated on the stack. This is quite important when you are programming on embedded device as stack can have a limited size compared to heap.
I recommend that you google Stack and Heap.
int* heapArray = (int*)malloc(10 * sizeof(int));
int stackArray[10];
Both are very similar in the way you access the data. They are very different in the way that the data is stored behind the scenes. The heapArray is allocated on the heap and is only deallocted when the application dies, or when free(heapArray) is called. The stackArray is allocated on the stack and is deallocated when the stack unwinds.
In the example you described int array[10] goes away when you leave your stack frame. If you would like the used memory to persist beyond local scope you have to use malloc();
Although you can do variable length arrays as of C99, there's still no decent substitute for the more dynamic data structures. A classic example is the linked list. To get an arbitrary size, you use malloc to allocate each node so that you can insert and delete without massive memory copying, as would be the case with a variable length array.
For example, an arbitrarily sized stack using a simple linked list:
#include <stdio.h>
#include <stdlib.h>
typedef struct sNode {
int payLoad;
struct sNode *next;
} tNode;
void stkPush (tNode **stk, int val) {
tNode *newNode = malloc (sizeof (tNode));
if (newNode == NULL) return;
newNode->payLoad = val;
newNode->next = *stk;
*stk = newNode;
}
int stkPop (tNode **stk) {
tNode *oldNode;
int val;
if (*stk == NULL) return 0;
oldNode = *stk;
*stk = oldNode->next;
val = oldNode->payLoad;
free (oldNode);
return val;
}
int main (void) {
tNode *top = NULL;
stkPush (&top, 42);
printf ("%d\n", stkPop (&top));
return 0;
}
Now, it's possible to do this with variable length arrays but, like writing an operating system in COBOL, there are better ways to do it.
malloc() is used whenever:
You need dynamic memory allocation
If you need to create array of size n, where n is calculated during your program execution, the only way you can do it is using malloc().
You need to allocate memory in heap
Variables defined in some functions live only till the end of this function. So, if some "callstack-independent" data is needed, it must be either passed/returned as function parameter (which is not always suitable), or stored in heap. The only way to store data in heap is to use malloc(). There are variable-size arrays, but they are allocated on stack.