How to assign NULL to structure member - c

Here is the code
struct stack {
int item;
struct stack *next=NULL;
};
I want to make the pointer initially point to null but this shows error
error:expected ':' , ',' , ';' , '}' or 'attribute' before'=' token

The fragment posted does not define an object, it defines a type.
In C you cannot specify the default value of a member in a type definition. You can specify the values of members in an initializer:
struct stack {
int item;
struct stack *next;
};
struct stack my_stack = { 0, NULL };
If you omit the last member in the initializer, it will be initialized to the zero of its type, NULL for a pointer:
struct stack my_stack = { 0 }; // my_stack.next is NULL

One creates a variable of that type, then puts initialization values in braces.
struct stack
{
int item;
struct stack *next;
} stackVar = { 0, NULL};

You cannot perform initializations inside of a struct definition. You can initialize a stack as such:
struct stack {
int item;
struct stack* next;
};
int main(){
struct stack s = {0,NULL};
}

You cannot ask your struct type to set that pointer to null by itself. You will have to do it explicitly every time you create an object of type struct stack, e.g.
struct stack my_stack = { .next = NULL };
or
struct stack my_stack = { 0 };
Both variants have the same effect - they set to zero all fields of my_stack.
If you create your struct stack objects in dynamic memory, then initialization syntax is out of question. You will have to explicitly assign the initial value to your freshly created object, e.g.
struct stack *my_stack = malloc(sizeof *my_stack);
my_stack->next = NULL;
or
struct stack *my_stack = malloc(sizeof *my_stack);
*my_stack = (struct stack) { 0 };
// or
*my_stack = (struct stack) { .next = NULL };

Related

How to initialize C structs with default values

I have this defined struct:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
typedef struct List {
int size = 0;
Node* head = NULL;
Node* tai = NULL;
} List;
List* list1;
For the the node one it is Ok, but for the List one I have a declaration error in visual studio (2022), I am new to C, how to declare default values in C structs?
In C, whether an object is initialized or not depends on how you declare the object, for example whether you declare it as an object of static storage duration (which is initialized to zero unless you explicitly initialize it to something else) or an object of automatic storage duration (which is not initialized, unless you explicitly initialize it).
Therefore, it would not make sense to assign default values to the type definition, because even if the language allowed this, it would not guarantee that the object of that type will be initialized.
However, you can create your own function which initializes your struct to specific values:
void init_list( List *p )
{
p->size = 0;
p->head = NULL;
p->tail = NULL;
}
Assuming that the object is declared inside a function (not at file scope), you can use the following code to declare and initialize the object to default values:
List list1;
init_list( &list1 );
If the object is declared at file scope, you can't call the function init_list at file scope, but you can call the function inside the function main, for example.
Alternatively, when you declare the object, you can also initialize the individual members:
List list1 = { 0, NULL, NULL };
This will also work at file scope.
Since everything is being initialized to zero, it is sufficient to write the following:
List list1 = { 0 };
In that case, all members that are not explicitly assigned a value will be initialized to zero.
In C opposite to C++ you may not initialize data members in structure declarations like you are doing
typedef struct List {
int size = 0;
Node* head = NULL;
Node* tai = NULL;
} List;
Also it does not make sense to declare the global pointer list1.
List* list1;
What you need is to write
typedef struct List {
int size;
Node* head;
Node* tail; // I think you mean `tail` instead of `tai`
} List;
int main( void )
{
List list1 = { .size = 0, .head = NULL, .tail = NULL };
//...;
In C you can't define a struct with default values for the members.
You can however create a global instance with the default values set that you then use for initialization. That's pretty common in the C world.
Example:
typedef struct List {
int size;
Node* head;
Node* tail;
} List;
// The init-value to use
const List List_INIT = {.size = 0, .head = NULL, .tail = NULL};
int main() {
List l = List_INIT; // using the init-value
}
typedef struct List {
int size;
Node* head;
Node* tail;
} List;
What you have defined here is a new data type, you haven't declared any variables of such a type. The name List is not a variable, it is the name of a structure type. The names size, head and tail are not variables, they're the identifiers for the members of this struct.
How to declare default values in C structs?
You can not define a type with default value for the members. Simply provide a definition for it with/after declaration:
List apple;
memset (&apple, 0x00, sizeof apple);
/* Or */
List apple = { .size = 0, .head = NULL, .tail = NULL };
/* Or */
List apple = { .size = 0, .head = 0, .tail = 0 };
/* Or */
List mango = { 0, NULL, NULL };
/* Or */
List banana = { 0, 0, 0};
/* Or */
List orange = { 0 };¹
[1] — §6.7.9 Initialization:
If there are fewer initializers in a brace-enclosed list than there
are elements or members of an aggregate, or fewer characters in a
string literal used to initialize an array of known size than there
are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage
duration

Expression must have struct or union type

I'm trying to make a stack / linkedlist implementation in C with. I'm struggling on the pop function of a stack.
Here's what my stack/linkedlist implementation looks like :
// a cell
struct cell_s
{
void *elem;
struct cell_s *next;
};
typedef struct cell_s cell_t;
// the list is a pointer to the first cell
struct linkedlist_s
{
struct cell_s *head;
int len;
};
typedef struct linkedlist_s linkedlist_t;
Here's the pop function :
/**
* Pop remove and return the head
*/
cell_t *pop(linkedlist_t *list)
{
if ((*list).len == 0) {
// we cannot pop an empty list
return NULL;
}
else
{
cell_t* tmp = (*list).head;
(*list).head = (*list).head.next; // <-- error occurs here
(*tmp).next = NULL;
return tmp;
}
}
I don't understand what I did wrong. (*list).head is a struct cell_s so I should be able to access the attribute next ? But compiler won't let me do it.
Thanks.
The head field is not a struct cell_s. It is a struct cell_s *, i.e. a pointer to struct cell_s. As such, you need to use the -> operator to dereference and access the member.
list->head = list->head->next;
Note also that ptr->field is easier to read than (*ptr).field.

C Data Structure Error [duplicate]

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.

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;
}

Store address dynamic array in c

I'm trying to save the address of a dynamic array index. The last line of this function is what gives the pointer error.
static struct sstor *dlist
struct node *ins_llist(char *data, struct llist *l) {
struct node *p, *q;
q = malloc((size_t)sizeof(struct node));
if(q == NULL)
return(NULL);
if(ins_list(data, &dlist))
return NULL;
q->item = &(dlist->item[(dlist->sz)-1]); // Problem?
...}
Allocation of dlist
struct llist *init_llist(void) {
struct llist *l;
dlist = init_list(INITSZ);
if(dlist == NULL)
return(NULL);
This is my node
struct node {
char **item;
struct node *next;
struct node *prev;
};
This is my array
struct sstor {
int sz;
int maxsz;
char item[][1024];
};
I'm still new to pointers. The line below gives the error: assignment from incompatible pointer type
q->item = &(dlist->item[(dlist->sz)-1]);
Presuming that you allocate an actual struct node for q to point to...
The "incompatible pointer types" error arises because q->item has type char ** (a pointer to a pointer to char), and &(dlist->item[...]) has type char (*)[1024] (a pointer to an array of 1024 char). These types simply aren't compatible (there is no actual "pointer to char" object for q->item to point to).
You can fix the problem in two ways. The first is by changing the declaration of struct node to this:
struct node {
char (*item)[1024];
struct node *next;
struct node *prev;
};
The second is by changing both the declaration of struct node to this:
struct node {
char *item;
struct node *next;
struct node *prev;
};
..and changing the assignment statement to this:
q->item = dlist->item[(dlist->sz)-1]; // No Problem!
(The first alternative makes q->item point to the entire array, and the second makes it point to the first char in the array. The perspecacious will note that these are pointers to the same location, but with different types. Usually, the second form is what you want).
char** is not the same as char[][1024]
Try to fix the sstor structure like this:
struct sstor {
int sz;
int maxsz;
char *item[1024];
};

Resources