This question already has answers here:
C : typedef struct name {...}; VS typedef struct{...} name;
(6 answers)
Closed 5 years ago.
I am creating a program that uses a basic stack in C. In this I have two structures defined in the heading:
A structure named Node with a string and a pointer to a previous Node as members.
A structure named Stack with a pointer to the last Node as member.
Here are the definitions of these structures in my header file:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
const char* string;
struct Node *prev;
};
typedef struct Stack {
size_t sizeOfStack;
size_t sizeOfElem;
struct Node *last;
};
One method giving me errors is CreateStack():
CreateStack: This function creates a stack (equivalent to a constructor).
(a) Name: CreateStack
(b) Return Type: A pointer to a stack allocated in the heap.
Here is my implementation
Stack* CreateStack() {
Stack* stack = malloc(sizeof(*stack));
if (stack == NULL) {
return NULL;
}//end of if
stack->sizeOfElem = 0;
stack->sizeOfStack = 0;
stack->last = NULL;
return stack;
}//end of CreateStack
But the compiler is spitting this out:
error: 'Stack {aka struct Stack}' has no member named 'last'
stack->last = node;
error: 'Stack {aka struct Stack}' has no member named 'last'
node->prev = stack->last;
error: 'Stack {aka struct Stack}' has no member named 'last'
Node *node = stack->last;
If someone could point out the issue here I would greatly appreciate it. I am confused as to why it is saying last is not a thing, yet prev defined in the same way in the other structure does not raise a flag. Thanks.
Fix the typedefs and it'll compile:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
const char* string;
struct Node *prev;
} Node ;
typedef struct Stack {
size_t sizeOfStack;
size_t sizeOfElem;
struct Node *last;
} Stack;
Stack* CreateStack() {
Stack* stack = malloc(sizeof(*stack));
if (stack == NULL) {
return NULL;
}//end of if
stack->sizeOfElem = 0;
stack->sizeOfStack = 0;
stack->last = NULL;
return stack;
}//end of CreateStack
Your typedef statement is incomplete, as you do not define a name for the type. Write the following.
typedef struct Stack {
size_t sizeOfStack;
size_t sizeOfElem;
struct Node *last;
}Stack;
Note the Stack at the end, which defines now type Stack being equivalent to struct Stack.
Related
This question already has answers here:
What to do if an uninitialized pointer was used to write memory?
(4 answers)
Closed 4 months ago.
I am fairly new to C and wanted to create a linked list.
For the list-elements I created a structure and wanted to initialize the head element in a function. The last element of the list shall contain a null-pointer so I know, when I reached the end. But if I initialize next to NULL inside the function, I get a "Segmentation fault (core dumped)"
I tried to Google this, but I didn't find an answer.
After that I put the code from the function into my main and it worked. But why? It is the exact same code.
Inside function:
#include <stdlib.h>
struct list_node
{
unsigned long value;
struct list_node *next;
};
void new_list()
{
struct list_node *cache;
cache->next = NULL;
}
int main()
{
new_list();
return 0;
}
Inside main:
#include <stdlib.h>
struct list_node
{
unsigned long value;
struct list_node *next;
};
int main()
{
struct list_node *cache;
cache->next = NULL;
return 0;
}
You declared a an uninitialized pointer that has an indeterminate value.
void new_list()
{
struct list_node *cache;
cache->next = NULL;
}
So dereferencing the pointer
cache->next = NULL;
invokes undefined behavior.
The same problem exists in the second program
int main()
{
struct list_node *cache;
cache->next = NULL;
return 0;
}
That is the second program also has undefined behavior.
What you should do is just write
int main()
{
struct list_node *cache = NULL;
return 0;
}
That is initially your list is empty. So initially neither object of the type struct list_node was allocated and the pointer cache is equal to NULL.
In the tree.h header, I declared "struct privates" in order to hide the global variables. (relevant snippet)
struct privates;
/*
* a tree
*/
typedef struct tree_node
{
struct tree *left;
struct tree *right;
struct tree_node *left;
struct tree_node *right;
float * info;
float distance_to_neighbor;
} tree_node;
typedef struct tree
{
/*in order to keep track of the kd-tree root*/
tree_node * _root;
/*pointer to internal variables struct*/
struct privates* _privates;
} tree;
struct privates* init_heap_tree();
etc....
In the implementation file kdtree.c , I defined the "struct privates": (relevant snippet)
tree* my_tree=NULL;
typedef struct privates
{
/*variables*/
int current_number_of_tree_nodes;
/*previous tree rebuild's node count*/
int previous_tree_size;
} privates;
privates* init_heap_tree()
{
return (privates*) calloc(1, sizeof (privates));
}
tree* tree_get_tree()
{
my_tree = get_pre_allocated_tree();
return my_tree;
}
etc...
Now in the memory management code, see relevant snippet of init_heap().
I’m attempting to set initialize values for struct members "tree_space->_privates->current_number_of_tree_nodes = 0;"
void
init_heap (int max_dimensions)
{
tree_space = (tree *) calloc (tree_HEAP_SIZE, sizeof (tree));
tree_space = get_pre_allocated_tree();
tree_space->_privates = init_heap_tree();
//THIS IS WERE COMPILE TIME ERROR OCCURS
tree_space->_privates->current_number_of_tree_nodes = 0;
tree_space->_privates->previous_tree_size =0;
//allocate memory based on tree_HEAP_SIZE
tree_space = (tree_node*) calloc (tree_HEAP_SIZE, sizeof (tree_node));
tree_set_k_dimensions (max_dimensions);
etc...
}
"error: dereferencing pointer to incomplete type "struct privates"
I don't want any other design pattern for information hiding perse, How can I resolve this error with the struct member access?
Thanks a million.
Only functions in kdtree.c can access the members of private, so you need to do the initialization there.
privates* init_heap_tree()
{
privates *rval = calloc(1, sizeof (privates));
rval->current_number_of_tree_nodes = 0;
rval->previous_tree_size = 0;
return rval;
}
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;
}
I've been trying to figure this out for a while now, but cannot find a solution. I am building a linked list and when I try to pass the list as a pointer to anything I get an error: Dereferencing Pointer to incomplete type.
Here is my struct declaration
typedef struct listStruct{
char *name;
int size;
boolean inRestStatus;
list *next;
}list;
and one of the many functions that do not work.
void addToList(list *l, char * name, int size){
list *tmp;
while(l->next != NULL){
l = l->next;
}
tmp = malloc(sizeof(list));
tmp->name = name;
tmp->size = size;
tmp->inRestStatus = NO;
tmp->next = NULL;
l->next = tmp;
}
and the header
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct listStruct list;
I have tried changing the struct declaration to
typedef struct listStruct list{
...
};
and received the error: request for member in something not structure or union.
If anyone has any ideas that'd be awesome.
Edit
The struct definition is/was in a main function in a seperate file than the function, I have since moved the definition to the header file.
It seems that you declared only typedef name in the header
typedef struct listStruct list;
Thus the module where function
void addToList(list *l, char * name, int size);
is defined does not know the definition of the structure.
You have to include the structure definition in the header as for example
typedef struct listStruct{
char *name;
int size;
boolean inRestStatus;
struct listStruct *next;
}list;
that it would be accessible in the module where the function is defined.
Take into account that this method
void addToList(list *l, char * name, int size){
list *tmp;
while(l->next != NULL){
l = l->next;
}
tmp = malloc(sizeof(list));
tmp->name = name;
tmp->size = size;
tmp->inRestStatus = NO;
tmp->next = NULL;
l->next = tmp;
}
is also wrong. For example l can be equal to NULL can't it?
Also simple copying pointers
tmp->name = name;
looks questionably. Should you allocate memory to store a copy of a string pointed to by argument name?
Apparently, you placed your struct declaration into some implementation file, and a wrong implementation file at that.
The typedef declaration that you have in your header
typedef struct listStruct list;
declares an incomplete type. You have to place this
typedef struct listStruct{
char *name;
int size;
boolean inRestStatus;
list *next;
} list;
into the header or at least into the same implementation file that uses the data fields of your struct. Where is it now? You have to describe your file structure in full detail.
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*)));