C struct and malloc problem (C) - c

It's amazing how even the littlest program can cause so much trouble in C.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
tree* tree = (tree*) malloc(sizeof(tree));
node *node = (node*) malloc(sizeof(node));
tree->nodes[0] = node;
return tree;
}
int main() {
return 0;
}
The compiler says:
main.c: In function 'initTree':
main.c:17: error: expected expression before ')' token
main.c:18: error: expected expression before ')' token
Can you please help?

You're using two variables named tree and node, but you also have structs typedefed as tree and node.
Change your variable names:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(tree)); /* different names for variables */
node* anode = malloc(sizeof(node));
atree->nodes[0] = anode;
return atree;
}
int main() {
return 0;
}

tree and node is your case are type names and should not be used as variable names later on.
tree *initTree() {
tree *myTree = (tree*) malloc(sizeof(tree));
node *myNode = (node*) malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;
}

Change (tree*) and (node*) to (struct tree*) and (struct node*). You can't just say tree because that's also a variable.

Change the body of initTree as follows:
tree* myTree = (tree *)malloc(sizeof(tree));
node *myNode = (node *)malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;

Don't use typedef'ed names as variable names, and there is not need to cast malloc(); in C.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
tree->nodes[0] = malloc(sizeof(node));
return malloc(sizeof(tree));
}
int main() {
return 0;
}

I second that Mehrdad's explanation is to the point.
It's not uncommon that in C code you define a variable with the same name as the struct name for instance "node node;". Maybe it is not a good style; it is common in, e.g. linux kernel, code.
The real problem in the original code is that the compiler doesn't know how to interpret "tree" in "(tree*) malloc". According to the compiling error, it is obviously interpreted as a variable.

Apart from the original question, this code, even in it's correct forms will not work, simply due to the fact that tree::nodes (sorry for the C++ notation) as a pointer to a pointer will not point to anything usefull right after a tree as been malloced. So tree->nodes[0] which in the case of ordinary pointers is essentially the same like *(tree->nodes), can't be dereferenced. This is a very strange head for a tree anyway, but you should at least allocate a single node* to initialize that pointer to pointer:
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(struct tree)); /* different names for variables */
/* ... */
/* allocate space for numNodes node*, yet numNodes needs to be set to something beforehand */
atree->nodes = malloc(sizeof(struct node*) * atree->numNodes);
node* anode = malloc(sizeof(struct node));
atree->nodes[0] = anode;
return atree;
}

Interestingly, it does compile cleanly if you simply write the allocations as:
tree *tree = malloc( sizeof *tree );
It is often considered better style to use "sizeof variable"
rather than "sizeof( type )", and in this case the stylistic
convention resolves the syntax error. Personally, I think
this example is a good case demonstrating why typecasts are
generally a bad idea, as the code is much less obfuscated if
written:
struct tree *tree = malloc( sizeof *tree );

Related

display contents of a single linked list, code crashes at exit

Here is my code in question
#include <stdio.h>
#include <stdlib.h>
typedef struct _node Node;
typedef void* Data;
struct _node
{
Data* data;
Node *next;
};
typedef struct _singleLinkedList SingleLL;
struct _singleLinkedList
{
Node *head;
Node *tail;
Node *current; //not used in this example
};
typedef struct _partls
{
int x;
int y;
}Parts;
Node *addhead(SingleLL *list, Data* data)
{
Node *newnode = (Node*)malloc(sizeof(Node));
if(newnode == NULL)
return NULL;
newnode->data = data;
if(list->head == NULL)
{
newnode->next = NULL;
list->tail = newnode;
}
else
{
newnode->next = list->head;
}
list->head = newnode;
return newnode;
}
typedef void(*DISPLAY)(void*);
void displayparts(Parts* part)
{
puts("part_x\t\tpart_y");
printf("%d\t\t%d\n",part->x, part->y);
putchar('\n');
}
void displaySingleLinkedList(SingleLL *list, DISPLAY display)
{
Node *current;
for(current = list->head; current != NULL; current = current->next)
display(current->data);
}
void initSLList(SingleLL *list)
{
list->head = NULL;
list->tail = NULL; //not used in this example
}
int main(void)
{
puts("\nlinked list test code");
SingleLL *sLinkedList;
//create an object
Parts *part1 = (Parts*) malloc(sizeof(Parts));
if(part1 == NULL)
{
puts("NULL");
exit(1);
}
part1->x = 32;
part1->y = 98;
//create one more object
Parts *part2 = (Parts*) malloc(sizeof(Parts));
if(part2 == NULL)
{
puts("NULL");
exit(1);
}
part2->x = 42;
part2->y = 18;
initSLList(&sLinkedList);
addhead(&sLinkedList, part2);
addhead(&sLinkedList, part1);
displaySingleLinkedList(&sLinkedList, (DISPLAY) displayparts);
return 0;
}
Question:
This is a test code, not a complete perfect looking snippet.It has flaws. I did try the debugger to pace it line by line... it breaks when executes the displayparts function, the debugger says: cannot access memory at address 0x0. Although it should be enough info, i think my mind has stalled and i can't figure it out.
Can you help spot the source of the problem/problems that crashes the code? What should i modify to make it work with no errors?
Your pointer handling seems off, in multiple places. Here,
void initSLList(SingleLL *list)
main():
SingleLL *sLinkedList;
initSLList(&sLinkedList);
initSLList is given the address of the pointer sLinkedList, i.e. a pointer to a pointer.
Also, you have
typedef void* Data;
Node *addhead(SingleLL *list, Data* data)
So since Data is a pointer, addhead expects a pointer to a pointer.
But you're giving it a pointer to a Parts structure.
Gcc warns about giving a pointer to an incompatible type in six different places. See what warning options your compiler has, and enable them.
I'd suggest very sparingly typedefing pointers to something that don't look like pointers, just to avoid confusions like this. It might be ok in some library interface though.
SingleLL *sLinkedList;
// ...
initSLList(&sLinkedList);
But initSLList() takes a SingleLL* while you're passing it a SingleLL**. I think you meant to declare sLinkedList as a concrete SingleLL rather than a pointer to one.
You should compile with warnings set to the most verbose level (-Wall in gcc will do the trick). This would have generated a warning for this and possibly other issues in the program. It's a great, although sadly not foolproof, way to protect yourself against the extreme ease of shooting yourself in the foot with C.

Typedef struct cannot be cast to pointer

I've seen this question in multiple posts but I have yet to find one that has a good explanation for me. Im trying to create a linked list but the struct nor the functions cant be called without getting the error cannot cast to a pointer. Its really bugging me. Any help would be appreciated on how to get this working right. Heres some of the code below thats the issue.
typedef struct node
{
void *data;
struct node *next;
} node;
node *head = NULL;
node* create(void *data, node *next)
{
node *new_node = (node*)malloc(sizeof(node));
if(new_node == NULL)
{
exit(0);
}else{
new_node->data = data;
new_node->next = next;
return new_node;
}
}
node* prepend(node *head, void *data)
{
node *new_node = create(data,head);
head = new_node;
return head;
}
void preload_adz(int adz_fd)
{
struct adz adz_info;
char adz_data[40];
char adz_text[38];
int adz_delay;
char adz_delayS[2];
read(adz_fd,adz_data,40);
strncpy(adz_text,adz_data + 2,40-2);
sprintf(adz_delayS, "%c%c",adz_data[0],adz_data[1]);
adz_delay = atoi(adz_delayS);
adz_info.delay = adz_delay;
strncpy(adz_info.text,adz_text,38);
head = prepend(head, (void*)adz_info); //<---This line throws the error
while(read(adz_fd,adz_data,40) > 0)
{
}
}
struct adz adz_info;
...
head = prepend(head, (void*)adz_info); //<---This line throws the error
The problem here is adz_info is not a pointer, it's the actual struct on the stack. Passing adz_info into a function will copy the struct.
You need a pointer to that struct. Use & to get its address. Once you have the pointer, you don't need to cast it to void pointer, that cast is automatic.
head = prepend(head, &adz_info);
Note that casting is a bookkeeping thing. Casting to void * doesn't turn a struct into a pointer, it says "compiler, ignore the declared type of this variable and just trust me that this is a void pointer".

How to make use of a structure pointer inside the structure itself

I am studying the following C code:
typedef struct msg *m_;
struct msg
{
long from;
long to;
m_ link;
};
m_ queue;
I would like to see an example that explains the role of the pointer, i.e. m_, of the structure inside the structure itself m_ link!
Thank you very much.
To be pedantic: link is a pointer. m_ is not a pointer, it's a typedef. It is used to avoid the need to say "struct msg* link;" inside the struct definition.
As answered in the comment above, the queue is represented by a pointer to the first item, which has a pointer to the second (if any), and so on until you reach a NULL pointer.
It's important to take care when building such lists that no node points to itself or to any precursor, or you get an infinite loop chasing to the tail.
Pointers to the structure type inside the structure itself are very often used for linked lists, trees, etc. In your example, it is referring to a queue implementation.
Here is a very minimal example of a stack implementation using a linked list. The functions require the address of a stack pointer, and an empty stack is a NULL pointer.
struct linked_stack
{
int data;
struct linked_stack *next;
};
void linked_stack_push(linked_stack **stck, int data)
{
struct linked_stack *node = malloc(sizeof(struct linked_stack));
if (node != NULL)
{
node->data = data;
node->next = *stck;
}
*stck = node;
}
int linked_stack_top(linked_stack **stck)
{
if (*stck != NULL)
return (*stck)->data;
return 0; /* stack is empty */
}
void linked_stack_pop(linked_stack **stck)
{
struct linked_stack *node = *stck;
if (*stck != NULL)
{
*stck = node->next;
free(node);
}
}
Example usage:
int main(void)
{
struct linked_stack *stack = NULL;
linked_stack_push(&stack, 10);
printf("top of stack = %d\n", linked_stack_top(&stack));
linked_stack_pop(&stack);
return 0;
}

malloc structure C

I can't understand why this litle code doesn't work ! i get it from C struct and malloc problem (C) (selected answer) and I wonder why it doesn't work for me.
any idea ?
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(tree)); /* different names for variables */
node* anode = malloc(sizeof(node));
atree->nodes[0] = anode; // <-------- SEG FAULT HERE !
return atree;
}
int main() {
tree* mytree = initTree();
return 0;
}
With a call to
tree* atree = malloc(sizeof(tree));
you have allocated a memory for tree object, so for a struct node** nodes pointer to (as it is a struct member), but it doesn't point to valid memory yet. You have to allocate also a memory for the nodes to which it is supposed to point to. For example:
atree->nodes = malloc( atree->numNodes*(sizeof (node*)));

Trouble with signature of function to add node to end of linked list

In a program I'm writing I need a linked list, so it's a pretty specific implementation. It needs:
the ability to add a node to the end
the ability to remove a node whose data matches a specified value
The data is a cstring, no more than 20 characters in length. I'm not very experienced with C and am getting errors with the following signature void addToEnd(llist root, char entery[51]). I tried replacing llist with node but then the error is "unknown type name node". How can I get rid of this?
Here's the code
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct node
{
char entery[51];
struct node* next;
} llist;
/*may be losing root address permanently*/
void addToEnd(llist root, char entery[51])
{
while(root->next != NULL)
root = root->next;
node last = malloc(sizeof(struct node));
root->next = last;
strcpy(last, entery);
}
int main()
{
struct node *root = malloc(sizeof(struct node));
root->next = NULL;
strcpy(root->entery, "Hello");
struct node *conductor = root;//points to a node while traversing the list
if(conductor != 0)
while(conductor->next != 0)
conductor = conductor->next;
/* Creates a node at the end of the list */
conductor->next = malloc(sizeof(struct node));
conductor = conductor->next;
if (conductor == NULL)
{
printf( "Out of memory" );
return EXIT_SUCCESS;
}
/* initialize the new memory */
conductor->next = NULL;
strcpy(conductor->entery, " world\n");
addToEnd(root, " at the");
addToEnd(root, " end");
/*print everything in list*/
conductor = root;
if(conductor != NULL)
{
while(conductor->next != NULL)
{
printf("%s", conductor->entery);
conductor = conductor->next;
}
printf("%s", conductor->entery);
}
return EXIT_SUCCESS;
}
One thing I'm unclear about, is in all the examples I've seen is they typedef the struct. Why? Let me elaborate: how do you know if you want to be passing just node or struct node. Also I don't really see the point, struct node isn't that much longer than a single typedef'd name.
Problems:
line 12: void addToEnd(llist root, char entery[51]) shall be void addToEnd(llist *root, char entery[51]). Here root must be a pointer type or you actually can not modify its value inside the function and make it visible outside the function.
line 16: node last = malloc(sizeof(struct node)); shall be struct node *last = malloc(sizeof(struct node));. Since in C you must reference a type name with the keyword struct, and also it shall be a pointer or it cannot be initialized with malloc.
As for your typedef question, I believe it is optional and people use it only for convenience. Personally I don't use typedef on a struct very often.
EDITED:
Also your code comes with bugs. Sorry I was only focusing on the syntax before.
Please notice that malloc in C don't assure you that the allocated memory is zeored, it's actually could be anything inside. So you need to fill it manually: to add a line last->next = NULL; at the end of addToEnd.
To refer to your struct of the linked list, use struct node, after the typedef, you can also use llist. You can also ues, as the linked question uses.
typedef struct node
{
char entery[51];
struct node* next;
} node;
In this style, you can use node the same as struct node.
The syntax error you are facing is, you misused the arrow operator ->, it's used with pointers of struct. For struct, use the dot operator .
So for the function
void addToEnd(llist root, char entery[51])
{
while(root->next != NULL)
root = root->next;
You should pass in a pointer:
void addToEnd(llist* root, char entery[51])

Resources