Pointing to structs in a linked list - c

We're trying to set the address of a struct to an address we are given but when we print out the address of the struct it seems to not be the same value as the address we are given.
/*a struct to keep block information*/
struct header{
int space;
int free; /* 1 = free space and 0 = full*/
struct header *nextHead;
struct header *prevHead;
};
typedef struct header node;
int myinit(int *array, int size){
int newSize = size;
node * nullPointer;
nullPointer = NULL; //make intermediatry node pointer for some bullshit reason
* (array) = newSize; /*store the size of the malloc at the first address*/
printf("Address : %p\n", &array[0]);
array++;
printf("Address after: %p\n", &array[0]);
/*initial block*/
node *root = (node *)&array; /*store the root at the next address available*/
printf("size of struct %lu\n", sizeof(struct header));
printf("%p\n", root);
root->space = newSize;
root->free = 1;
root->nextHead = nullPointer;
root->prevHead = nullPointer;
}

In the line
node *root = (node *)&array;
You're taking the address of "array" local variable. IOW, you take the address of value that's on the stack, not what you are expecting. You have to modify the function's signature like this:
int mymain(int **myarray, int size);
and modify its definition accordingly. Then, you can write:
node *root = (node *)array;

node *root = (node *)&array;
Here you obtain address of a pointer and cast it to other pointer. You should not do this. Here you must allocate the memory for the node:
node * root = (node *) malloc(sizeof(node));
// or this allocates the memory and puts zeros to it
node * root = (node *) calloc(1, sizeof(node));
Also, you don't need any nodes which points to NULL, you can simply use NULL like this:
node->nextHeader = NULL;

Also, instead of using &array[0], use array in this piece of code.
You will become less confused with pointers if you keep to simple code and understand every line you write. When you have a lot of ampersands and special signs in one line you're probably doing something wrong, train your spider sense for those situations.

Related

what difference between direct pointer and indirect pointer? [duplicate]

This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 8 months ago.
pointer to a struct
code that can not work
struct node
{
/* data */
int data;
};
void addnode(struct node* n)
{
n = (struct node*)malloc(sizeof(struct node));
printf("value of pointer n = %p",&n);
(*n).data = 9;
}
int main()
{
struct node * n1 = NULL;
addnode(n1);
printf("data is %d\n",n1->data);
}
but the code below is fine
struct node
{
/* data */
int data;
};
void addnode(struct node ** n1)
{
// the address of struct
*n1 = (struct node*)malloc(sizeof(struct node));
printf("address of pointer &n1 = %p\n",&n1);
printf("address of pointer *n1 = %p\n",*n1);
(*n1)->data = 99;
}
int main()
{
struct node * n1 = NULL;
//pass the address of pointer instead of value of it
addnode(&n1);
printf("address of pointer &n1 = %p\n",&n1); // self address
printf("address of pointer *n1 = %p\n",&(*n1)); // the address of struct
printf("data is %d\n",n1->data);
}
what makes me confused is why the indirect pointer as a parameter is working, instead of the direct pointer.
The 'indirect' pointer, as you called it, is actually 'a pointer to your pointer variable'.
If you inspect the value of n1 in your debugger, you will see, in your first example, that it will remain NULL (because you did not assign a new value to it).
In the second example however, you assign a value to the variable by accessing it's address.
Your first code can work too if it looks like this:
struct node
{
/* data */
int data;
};
struct node* addnode()
{
struct node* n = (struct node*)malloc(sizeof(struct node));
printf("value of pointer n = %p",&n);
n->data = 9;
return n;
}
int main()
{
struct node * n1 = NULL;
n1 = addnode();
printf("data is %d\n",n1->data);
}

why there is difference in address but still pointing to the same data?

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node {
int data;
struct node * next;
};
int main() {
struct node * head = (struct node * ) malloc(sizeof(struct node));
head -> data = 10;
head -> next = (struct node * ) malloc(sizeof(struct node));
head -> next -> data = 20;
head -> next -> next = NULL;
int noOfNodes = 2;
char * buff = malloc(50);
strncpy(buff, (char * ) & noOfNodes, sizeof(int));
// strncpy(buff+4,(char *)head,sizeof(struct node *));
memcpy(buff + 4, (char * ) head, sizeof(struct node * ));
printf("noOfNodes: %d\n\n", *(int * ) buff);
printf("1]<%p><%d>\n", head, head -> data);
printf("2]<%p><%d>\n\n", ((struct node * ) buff + 4), ((struct node * )(buff + 4)) -> data);
printf("address of next node \n");
printf("3]<%p>\n", head -> next);
printf("4]<%p>\n", ((struct node * )(buff + 4)) -> next);
return 0;
}
Ouput:
noOfNodes: 2
1]<0x56450bd632a0><10>
2]<0x56450bd63320><10>
address of next node
3]<0x56450bd632c0>
4]<(nil)>
why there is difference in address ?
1] ends with ...2a0
2] ends with ...320
if address is different then how come it pointing to the variable data(...->data) correctly ?
why is (buff+4)->next is NULL? it should be same as head->next (i.e. <0x56450bd632c0>).
struct node *n1 = head;
when we do this irrespective of how large the struct node this only needs 8bytes to store(as we are storing address of struct node).
i want to do this using memcpy() (using only 8 bytes)store only the address of struct node head and not all struct node in (buff+4).
how to do this ? thats why i used (struct node *).
[tl;dr]   To copy the entire *head to buff+4 the memcpy line needs to be changed as follows.
memcpy(buff+4, (char *)head, sizeof(struct node)); // instead of sizeof(struct node *)
With OP's code, assuming the likely case of 32b integers and 64b pointers:
struct node is padded to satisfy the pointer alignment requirements
struct node
{
int data;
int hidden_padding_field; // <--- inserted by the compiler
struct node *next;
};
the following copies 8 bytes from head to buff+4, meaning head->data and hidden_padding_field get copied, but head->next does not.
memcpy(buff+4, (char *)head, sizeof(struct node *));
Consequently, the data value gets copied correctly, but the next pointer is left unitialized. That it happens to be NULL is entirely by accident, just one possible manifestation of undefined behavior.
why there is difference in address ?
Because the buff array is a different chunk of memory from the one that was malloced for the head, so buff+4 is a different place in memory.
if address is different then how come it pointing to the variable data(...->data) correctly ?
Because you memcpyd some memory into the buff at that location, copying it from the memory that head points at. So although it is a different chunk of memory, it has the same data written into it.
why is (buff+4)->next is NULL?
Because you did not copy enough memory, so the part where the next member should be is still whatever was in that part of the buff before the copy. This happened because you told memcpy to copy as much memory as a struct node * takes up; but you didn't want to copy a chunk of memory that was a pointer, you wanted to copy a chunk of memory that was the node itself. So it should have said sizeof(struct node) instead of sizeof(struct node *).
The struct node structure starts with int data, and int might be the same size as any ordinary pointer (at least, I can't think of any situations where it would be bigger). So when we look at the memory that starts at the location buff + 4, it seems we copied enough data there to put the correct value into the ->data, but not enough to do anything about the ->next.

Value of struct variable changes after malloc of other variable of same struct

So i am trying to initiliaze a node of a graph. The problem is that the value of the variable node->edges_capacity changes from 2 to some random int for no apparent reason, at least to my knowledge.
Moreover, when i use the debug mode of CLion, it prints 2 as expected!
Am i doing something wrong with malloc?
typedef struct node {
int id;
int degree;
int edges_capacity;
struct node **edges;
} Node;
Node *node_create(int id) {
Node *node = (Node *) malloc(sizeof(Node *));
if (node == NULL)
exit(1);
node->id = id;
node->degree = 0;
node->edges_capacity = 2;
node->edges = (Node **) malloc(node->edges_capacity * sizeof(Node *));
node_debug(node); // prints a random int for node->edges_capacity instead of 2
return node;
}
void node_debug(Node *node) {
printf("id:%d degree:%d capacity:%d\n", node->id, node->degree, node->edges_capacity);
}
this line:
Node *node = (Node *) malloc(sizeof(Node *));'
has a couple of problems.
need to be allocating enough room for the full size of a Node, not a pointer to a Node.
when call any of the heap allocation functions (malloc, calloc, realloc) the returned type is void*, which can be assigned to any other pointer. Casting the returned value just clutters the code, making int much more difficult to understand, debug, maintain.
The following, posted code is writing to areas in the heap memory that the program does not own. This is undefined behavior and can lead to a seg fault event. Your noticing one aspect of that undefined behavior.
Change this line :
Node *node = (Node *) malloc(sizeof(Node *));
to :
Node *node = malloc(sizeof(Node));
as you declare node to be a pointer to type Node, and not to Node *.
Also, see this link on why not to cast the result of malloc.

pass scanf value to struct pointer Segmentation Fault

All I want to do is a basic printing with a struct pointer using user input. I got a segmentation fault when I try to do with below code. I'm new to c, thanks anyway.
typedef struct {
int *licenseNum;
char *name;
char *region;
} City;
typedef struct {
struct Node *current;
struct Node *head;
struct Node *tail;
struct Node *next;
struct Node *secondNext;
City *data;
} Node;
int main()
{
Node *node = malloc(sizeof(Node));
City *city = malloc(sizeof(City));
puts("License number of the City: ");
scanf("%d", &(node -> data -> licenseNum));
printf("%d", node -> data -> licenseNum);
return 0;
}
You didn't set data in node.
Node * node = malloc(sizeof(Node));
City * city = malloc(sizeof(City));
// node->data is not yet defined!
// It has a random value! You must first initialize it:
node->data = city;
Also you shouldn't use malloc here as memory allocated by malloc has random values. Only use malloc if you for sure initialize all the pointers in a struct with meaningful values prior to using them. It's much safer to use calloc:
Node * node = calloc(1, sizeof(Node));
City * city = calloc(1, sizeof(City));
node->data = city;
calloc works like malloc, but it guarantees that the returned memory is all set to zero (all int values are 0, all pointers are NULL). The first argument of calloc (1 in the code above) is the number of items you want to allocate, here it is just one. E.g. calloc(5, sizeof(City)) would allocate memory for 5 cities in a single block, e.g.:
Cities * cities = calloc(5, sizeof(City));
cities[0].name = "New York";
cities[1].name = "London";
// ... and so on
You didn't initialize node->data.
You allocated memory for node, but not for node->data.
You probably wanted to do this: node->data = city

Malloc struct with double pointer

I have a structure that looks like this:
typedef struct{
char* name;
int count;
Node **subnodes;
}Node;
I receive name and count over network one by one for the whole k-ary tree and then I reconstruct the tree. How do I malloc this struct?
Node *n = NULL;
fun(n, buf); //call function fun
void fun(Node *n, void *buf){
//successfully extracted name and count from buf
// say count is 5, i.e. this node should have 5 subnodes and
// name is root
n = malloc(sizeof(*n)+strlen(name));
n->name = name;
n->count = count;
for(int i=0; i<n->count;i++)
fun(n->subnodes[i], buf+some_increment);
}
This crashes as soon as I call fun for the second time. How should I malloc properly? Should I be malloc-ing each subnode?
First off, you realise this is leaky? n is just on the stack - you aren't returning it or "saving" the value you give it anywhere permanently.
Then you haven't actually allocated any memory for subnodes, so by indexing into it you are reading unallocated memory.
Without a more complete example it is hard to further, but at a minimum you need to malloc something for subnodes.
Yes, you will have to malloc each node. I see a couple of issues here:
You are neglecting in malloc(sizeof(*n)+strlen(name)) to provide space for the null terminator. This statement should read malloc(sizeof(*n)+strlen(name)+1). Also you should set the name pointer in the struct to the end of the struct and then strcpy the buffered name to it
n -> name = (char *)(n + 1)
strcpy(n -> name, buffered_name)
I presume the buffered version is transient.
You are allocating no space for the variable sized array of child nodes. This has to be done as a separate malloc or you have to embed it in the Node malloc (I'd recommend placing it between the Node header and the name string content.
Note, I am making a few liberal assumptions about what the code really looks like since this is clearly an incomplete snippit with typos. e.g. subnodes <-> subnode
Addendum: Code snippet (untested so normal caveats apply):
typedef struct
{
char* name;
int count;
Node **subnodes;
}
Node;
Node *fun(void *buf)
{
...
//successfully extracted name and count from buf
// say count is 5, i.e. this node should have 5 subnodes and
// name is root
// Allocate space for the node and its data.
Node *node_ptr = malloc(sizeof(Node) + count * sizeof(Node *) + strlen(name) + 1);
// Set the name pointer and copy the name from the I/O buffer.
node_ptr -> name = (char *)(node_ptr + 1) + count * sizeof(Node *); // set the name pointer to the right location.
strcpy(node_ptr -> name, name); // copy the buffered value to the node value.
// Establish the count from the I/O buffer.
node_ptr -> count = count;
// Set the subnodes address.
node_ptr -> subnodes = (char *)(node_ptr + 1);
// Get the child nodes.
for(int child = 0; child < node_ptr -> count; child++)
node_ptr -> subnodes[child] = fun(buf + some_increment);
}
I have a structure that looks like this:
typdef struct{
char* name;
int count;
Node **subnodes;
}Node;
Not really, because it is typedef not typdef.
As John3136 pointed out, your function allocates memory in n which is a local variable. Plus you are assigning count and name which do not appear to be passed to fun.
It also looks to me like the function fun will recurse indefinitely.
You call fun which (in the last line) calls fun which therefore calls fun again, and so on until you run out of stack.
(Edited to add)
Trying to guess what is wanted, I have got this working example going:
#include <memory.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct Node {
char* name;
int count;
Node **subnodes;
}Node;
void makeNode(Node * &n, const char * name, const int count)
{
// make the node itself
n = (Node *) malloc(sizeof(*n));
// allocate room for the name
n->name = (char *) malloc (strlen (name) + 1);
// copy in the name
strcpy (n->name, name);
// save the count of subnodes
n->count = count;
// allocate memory for subnode pointers (not the subnodes themselves)
if (count > 0)
n->subnodes = (Node **) malloc (sizeof (Node *) * count);
else
n->subnodes = NULL;
} // end of makeNode
int main ()
{
Node *node = NULL;
makeNode(node, "foo", 3);
makeNode(node->subnodes [0], "the", 0);
makeNode(node->subnodes [1], "slithy", 0);
makeNode(node->subnodes [2], "toves", 0);
for (int i = 0; i < 3; i++)
printf ("Node %i, name = %s\n", i, node->subnodes [i]->name);
printf ("Done!\n");
} // end of main
This runs OK:
Node 0, name = the
Node 1, name = slithy
Node 2, name = toves
Done!
Note, I compiled with g++, not gcc. However it should give you some ideas to go on with.
(You don't have references in C, so you really need C++ for this to work)

Resources