Error when accessing allocated memory in c - c

If understand my own code correctly I am allocating space for 3 pointers pointing to a data type ListNode and then looping three times and adding a number to each node.
I know that the nodes are not connected to one another
now when I try to access any node from the allocated space I get the error commented in the bottom of the code
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int val;
struct ListNode *next;
} ListNode;
int main(void)
{
int nums[] = {2,3,4};
ListNode * ptr = (ListNode*)malloc(3*sizeof(ListNode*));
for (int i=0; i < sizeof(nums)/sizeof(nums[0]); i++ )
{
ListNode new;
new.val = nums[i];
ptr[i] = new;
}
printf("%d \n",ptr[0].val);
free(ptr);
return 0;
}
/*
Error:
malloc(): corrupted top size
Aborted (core dumped)
*/
why do I get this error and how to properly access each node in the allocated space

You're not allocating enough space:
ListNode * ptr = (ListNode*)malloc(3*sizeof(ListNode*));
Here you're attempting to dynamically allocate a 3 element of array of ListNode structs, but you're instead allocating space for 3 pointers to ListNode. These pointers are smaller that the structs, so you end up writing past the end of allocated memory, triggering undefined behavior and a crash.
You want to allocate space for 3 structs, not 3 pointers:
ListNode * ptr = (ListNode*)malloc(3*sizeof(ListNode));
Or better yet:
ListNode * ptr = (ListNode*)malloc(3 * sizeof *ptr);
As this doesn't depend on what the type of ptr is.

int nums[] = {2,3,4};
size_t k = sizeof(nums)/sizeof(nums[0]);
ListNode * ptr = malloc(k*sizeof(ListNode));
Do not cast the malloc's result for reasons you can find in many places, including on SO.
Allocate COUNT times sizeof(object), not sizeof(object*) bytes.

Related

strncpy vs direct assignment seg fault

The following code below runs without a seg fault
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char *data;
struct node *next;
};
int main(void)
{
struct node *head = malloc(sizeof(struct node));
head->data = "test";
printf("data: %s\n", head->data);
return 0;
}
when I switch the code to so
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char *data;
struct node *next;
};
int main(void)
{
struct node *head = malloc(sizeof(struct node));
strncpy(head->data, "test", 512);
printf("data: %s\n", head->data);
return 0;
}
I receive a seg fault and am forced to switch my node property data to be of type char data[512]. Why is this required? I thought arrays are inherently pointers, so this behavior is not making sense to me.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char data[512];
struct node *next;
};
int main(void)
{
struct node *head = malloc(sizeof(struct node));
strncpy(head->data, "test", 512);
printf("data: %s\n", head->data);
return 0;
}
I expected that both pointers and arrays could be assigned string values in the same way.
In this statement
head->data = "test";
the string literal having the array type char[5] is implicitly converted to pointer to its first element and this pointer is assigned to the pointer head->data.
In this statement
strncpy(head->data, "test", 512);
you are using an uninitialized pointer head->data and trying to copy the whole string literal to the memory pointed to by that pointer with an indeterminate value. That invokes undefined behavior.
I thought arrays are inherently pointers, so this behavior is not
making sense to me.
Arrays are not pointers. They can be implicitly converted to pointers to their first elements in most situations but this does not mean that arrays are pointers.
Consider the simple demonstration program below.
#include <stdio.h>
int main( void )
{
char data[512];
char *p = data;
printf( "sizeof( data ) = %zu\n", sizeof( data ) );
printf( "sizeof( p ) = %zu\n", sizeof( p ) );
}
Its output might look like
sizeof( data ) = 512
sizeof( p ) = 8
In the second snippet (the one that crashes), you allocate memory for the node struct, which includes the pointer data. However, this pointer is never initialized, and it points to some arbitrary memory address (or just NULL), meaning that writing to it is undefined behavior, and indeed likely to just segfault.
For it to point to a valid memory address, you'll have to explicitly allocate it:
struct node *head = malloc(sizeof(struct node));
head->data = malloc(sizeof(char) * 512 /* or some other size, of course */);
Why is this required? I thought arrays are inherently pointers, so this behavior is not making sense to me.
Pointers are just pointers and the only memory they occupy is the memory required to store an address. If you want a pointer to point at dynamically allocated memory, you need to allocate it yourself.
Example:
struct node {
char *data;
struct node *next;
};
struct node *create_node(const char *str) {
struct node *nn = malloc(sizeof *nn);
if(nn) {
nn->data = strdup(str); // allocate strlen(str)+1 bytes and copy the string
if(nn->data) { // strdup was successful
nn->next = NULL;
} else { // strdup failed
free(nn);
nn = NULL;
}
}
return nn;
}
void destroy_node(struct node *n) {
free(n->data);
free(n);
}
I thought arrays are inherently pointers
Array Vs pointer:
An array might decay to a pointer in expressions and function parameters, and array accesses might be rewritten by the compiler as pointer accesses, but they are not interchangeable. An array name is an address, and a pointer is the address of an address.
Why is this required?
Declaring a pointer only allocates memory for the pointer.
You can initialise a pointer in two ways:
Either with a string literal:
ptr = "abcd";
Originally, ptr was
indeterminate. But this changes
what it was pointing to such that
it now points to a string literal.
The compiler will store the
address of the first element of
the string literal in ptr.
If you were to do the same with an
array:
char s[] = "String";
and then try to change its value:
s = "String2";
/* error: assignment to expression
with array type */
It wouldn't compile, because
arrays, unlike pointers, are not
modifiable lvalues.
You can't change its value.
Or allocate memory for it and then
write to it.
errno = 0;
ptr = malloc (size);
if (!ptr) {
errno = ENOMEM;
perror ("malloc ()");
deal with error here...
}
Now you can use strcpy () to
copy to it.

Can I malloc only the exact memory needed for an input string and point it?

I'm making a program where I save input strings from fgets in a list, they have a fixed maximum lenght but can also be shorter; i save them like this:
typedef char line[LINE_SIZE];
struct node{
line *t; //pointer and not just a variable so I can "detach" the allocation to do stuff
struct node *prev;
struct node *next;
};
but, in my program I just do malloc(sizeof(line)) which is an array with the maximum fixed lenght.
My question is, if I were to allocate something like malloc( strlen( str ) + sizeof( ( char )'\0' ) ) to precisely use only the memory needed, how can I point it?
Is it okay using a char* inside the node struct? Do I risk something?
I have heard about flexible arrays inside the structs but I don't want to put the array directly inside the struct, because for the program I need to be able to detach it and then point to it with another pointer
malloc() returns the address it allocated, you can assign the return value to a variable and point it. You don't need to always allocate maximum or the same size of memory even though the variable is the same member of a struct.
char* line=malloc(strlen(str)+1); // +1 for null terminate
strcpy(line, "This is a str"); // points the memory of returned
Using a char* in a struct is absolutely fine. Please treat a member of struct like a plain variable.
struct node
{
char* t;
struct node* prev;
struct node* next;
}
node n;
n.t = malloc(strlen(str) + 1); // it's fine.
strcpy(n.t, "This is a node"); // using the memory you allocated above
n.prev = n.next = NULL;
... // doing some processing
free(n.t); // don't forget to call free() when you're done using the memory.
For your purpose, you must allocate the node structure and the line fragment separately.
Depending on what the rest of the code assumes, you could allocate just the space for the string for each line instead of a full array, but you must change the node structure to use a char *t; instead of a line typedef. Note that it is very confusing to typedef arrays.
The only caveat is you must be careful when modifying these strings as you cannot add any characters at the end, nor insert any characters by moving contents beyond their allocated length. As a rule of thumb, if you reallocate these strings whenever you modify them, you should be safe.
Here is a simple example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char *t; //pointer and not just a variable so I can "detach" the allocation to do stuff
struct node *prev;
struct node *next;
};
struct node *read_file(FILE *fp) {
char buf[128];
struct node *head = NULL, tail = NULL, *n = NULL;
while (fgets(buf, sizeof buf, fp)) {
buf[strcspn(buf, "\n")] = '\0'; // strip the trailing newline if present
n = malloc(sizeof(*n));
if (n == NULL)
abort();
n->prev = tail;
n->next = NULL;
n->t = strdup(buf);
if (n->t == NULL)
abort();
if (tail == NULL) {
head = n;
} else {
tail->next = n;
}
tail = n;
}
return head;
}

Segmentation fault using malloc/struct

I am trying to code an easy list in C, which is able to store numbers.
With number SIZE, an index will be calculated and the numbers have to be stored in a kind of linear list at the array index.
However, sometimes I get a "segmentation fault", like 2 of 10 tries the output is correct.
I've gone a long search, but I couldn't find the problem.
Please keep in mind that my "solution" isn't implemented fully, so currently it's only working when the calculated index has no pointer thats stored. (Couldn't continue to code because of the error.)
Here is my code:
#define SIZE 3
#define NULL 0
typedef struct node_s node_t;
struct node_s {
node_t* next;
int number;
};
static node_t nodeArray[SIZE];
int addNumber(int numb){
int index = number % SIZE;
if(nodeArray[index].next == NULL){
node_t* node = (node_t*) malloc(sizeof(node_t));
node->number = number;
nodeArray[hash].next = node;
}
}
void print(){
for(int i = 0; i < SIZE; i++){
node_t* ptr = nodeArray[i].next;
while(ptr != NULL){
printf("%d -> ", ptr->number);
ptr = ptr->next;
}
printf("\n");
}
}
#include "dictionary.h"
#include <stdio.h>
int main(){
insert(1);
insert(2);
print();
return 0;
}
What causes the "segmentation fault" sometimes?
I appreciate any kind of help, thanks in advance!
Just after malloc you do init one member.
node->number = number;
But you do not init the other member, there is no
node->next = NULL;
Also, in your loop condition inside print(), you check ptr against NULL, but that is in most of the looping the non-initialised ptr->next from previous loop.
ptr = ptr->next;
I.e. you rely on it to be initialised to NULL.
That is probably causing the segfault.
Useful background, as pointed out by yano (thanks):
Malloc doesn't initialize memory to 0. In order to do that you can malloc followed by a memset or you can use calloc.

deallocating array of struct pointers in c implementation of priority queue

I have an issue freeing my array of struct pointers for a priority queue that I am implementing. I create two dynamic arrays of node pointers with a fixed size from client c program. The array heapMap contains node pointers that map to each created node with a specific ID integer value and the array heap is the heap array that contains the nodes with respect to their current values.
Everything seems to work, however, my pq_free function seems to cause errors or doesn't properly deallocate the arrays. Any help would be appreciated
Structures
typedef struct node_struct{
int ID;
double val;
}NODE;
struct pq_struct {
char heapType;
int max;
int inUse;
NODE ** heap; //BOTH have a specific capacity
NODE **heapMap; //array of pointers to each
};
This is the function I use to allocate memory for the structure.
PQ * pq_create(int capacity, int min_heap){
PQ * newQueue = (PQ*) malloc(sizeof(PQ)); //Allocate memory for a new heap
newQueue->max = capacity;
newQueue->inUse = 0;
int inUse = 1;//1 in use by default, the 0th point in the array is left alone intentionally
//If min_heap == 0, it it is a max heap, any other value is a min heap.
if(min_heap != 0){
newQueue->heapType = 'm';
}else{
newQueue->heapType = 'M';
}
//Allocate memory for heapMap and heap..
newQueue->heap = (NODE**) malloc(sizeof(NODE*)*capacity); //array of nodes, the heap
newQueue->heapMap = (NODE**) malloc(sizeof(NODE*) * capacity);//array of node pointers, the HEAPMAP
int i = 0;
for (i = 0; i < capacity + 1;i++) {
newQueue->heapMap[i] = NULL;
}
//return PQ pointer
return newQueue;
}
This is my pq_free function that doesn't seem to work properly. Thanks for help in advance.
void pq_free(PQ * pq){
//free all nodes
NODE * temp;
NODE ** temp2;
int i;
for (i = 0; i < pq->inUse; i++) {
if (pq->heapMap[i] != NULL) {
temp = pq->heapMap[i];
free(temp);
}
}
//pq->heapMap = NULL;
free(pq->heap);
free(pq->heapMap);
free(pq);
}
As I was once railed on this site for doing this, I feel obligated to do the same to you. You shouldn't cast malloc because it is automatically cast to the assigned data type and can lead to some bad situations.
Other than that how are the individual nodes allocated? What errors specifically are given? I think you are also walking off your heapMap as you allocate capacity but iterate over capacity + 1 elements.

Loop allocation of linked list inside inline struct not allocating memory

I have strange problem with allocating a linked list in a loop.
Consider a simplified source code :
struct main_s {
minor_s minor_structure; (inline)
};
struct minor_s {
list_s *first_dir;
};
struct list_s {
anotherlist_s *first_object;
list_s *next;
};
struct anotherlist_s {
//multiple fields
};
And i have a basic init/deinit functions like :
struct main_s *main_s_init();
void main_s_deinit();
And now i'm kinda riddled with allocating in loop :
im passing to this function main_s->minor_structure.first_dir and, how_many parameter, defining how many linked nodes going to be initiated.
void loop_inittiation(struct list_s *list, int how_many) {
int i;
struct list_s *tmp = list;
for(i = 0; i < how_many; i++) {
tmp = malloc(sizeof(struct list_s));
tmp = tmp->next;
}
}
And this is where i have problem, im allocating the temporary "tmp" instead of the pointed structure. I understand that to allocate a pointer by tmp u have to use double pointer, but it still doesnt work. What am i missing? In gdb there is no memory space allocated :/.
Do i have to use **tmp?
You've got the right idea about what's wrong. The local copy of tmp in the function is changed, but once you're outside, that value is lost. If you want to change a variable inside a different function in C, you MUST pass the address of the thing you want to change. If the thing you want to change is already a pointer, you must pass the address of the pointer (or double pointer). If it's a double pointer you want to change, then you have to pass a triple pointer. If it's a 123141 pointer, you have to pass a 123142 pointer :)
Change the parameter to the function to:
&(main_s->minor_structure.first_dir)
Just change the input parameter to
struct list **list
change tmp to a double pointer to match it, then each time you use tmp, make sure to throw in an extra dereference..
struct list_s **tmp = list
and
*tmp = malloc(sizeof(struct list_s));
*tmp = (*tmp)->next;
So it would look like:
void loop_inittiation(struct list_s **list, int how_many) {
int i;
struct list_s **tmp = list;
for(i = 0; i < how_many; i++) {
*tmp = malloc(sizeof(struct list_s));
tmp = &((**tmp)->next);
}
}
Another way to do it is to leave the tmp stuff alone, as a single pointer, store the first node you allocate, and then just say
*list = tmp;
But then you do have to treat that first allocation as a special case.

Resources