I wanted to make an array of stacks in C, where I should be able to retain individual stacks and their respective information. I currently have the following implementation, which only works for one stack. How can I modify the functions push and pop to achieve multiple stacks each using the same function.
(I was easily able to do this in Java, as I could create a class, but I have no idea in C)
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *first = NULL;
void push(int x) {
struct node *newnode = malloc(sizeof(struct node));
newnode->data = x;
newnode->next = first;
first = newnode;
}
int pop() {
int temp = first->data;
first = first->next;
return temp;
}
You have a memory leak in your code in the pop() function. You should free the memory that you have malloc'd.
Taking advice from #Jongware's comments below your question.
Here's a new version of the push() and pop() functions.
#include <stdlib.h>
struct node {
int data;
struct node *prev;
};
void push(struct node **stack, int x) {
if (stack != NULL)
{
struct node *newnode = malloc(sizeof(struct node));
newnode->data = x;
newnode->prev = *stack;
*stack = newnode;
} else
{
// You didn't give me a valid pointer to a stack, so I'm ignoring you!
}
}
int pop(struct node **stack) {
int temp = 0; // This is the default value that is returned when there is an error.
struct node *oldnode;
if (stack != NULL)
{
if (*stack != NULL)
{
oldnode= *stack;
temp = oldnode->data;
(*stack) = oldnode->prev;
free(oldnode);
} else
{
// The stack is empty. I will just ignore you and return the default value for temp.
}
} else
{
// You didn't give me a valid pointer to a stack so I'm ignoring you and returning the default value of 0 for temp!
}
return temp;
}
And here's an example of how to use them:
#include <stdio.h>
int main()
{
struct node *stack1 = NULL, *stack2 = NULL;
int value;
// Push some values onto the stacks
printf("Pushing 7 and then 8 onto stack1\n");
push(&stack1, 7);
push(&stack1, 8);
printf("Pushing 3 onto stack2\n");
push(&stack2, 3);
// Pop and print both stacks
value = pop(&stack2);
printf("Popped %d from stack2\n", value);
value = pop(&stack1);
printf("Popped %d from stack1\n", value);
value = pop(&stack1);
printf("Popped %d from stack1\n", value);
return 0;
}
As for where you should be declaring your stack pointers that is really up to you and how you intend to use them.
Have a read about C variable scope for some options and how you might use them.
Also, I will have to include a warning with declaring these pointers inside functions. In whichever function you declare your pointer you must make sure that you pop everything off the stack before you exit the function, otherwise you will lose the pointer and leak all the allocated memory. If this is not what you want, or you want the pointer to outlive the function then you can declare the pointer globally or pass it around, making sure that everything is popped off the stack before your program exists or loses the pointer.
Another thing that you might want to consider is what happens when you use pop() on an empty stack? The implementation that I have given you simply returns 0 and ignores you. You might want to handle that a little better.
You can only have one stack because you defined it as a global variable:
struct node *first = NULL;
In Java you would have used a class. In C, you can likewise do "object based" programming by defining an abstract data type which holds your instance variables, instead of using global variables:
struct stack {
struct node *first;
};
there are no class features like constructors or destructors, so you write functions to initialize a stack, destroy a stack and so forth. To achieve multiple instantiation, you explicitly pass a stack * argument to each function in the stack module.
You might want to name your functions in some consistent way, like stack_init, stack_cleanup, stack_push and so on.
There are design questions to settle such as: does the caller allocate struct stack, for which you provide stack_init function? Or do you provide a one-step stack_alloc function that allocates and returns a stack? Or perhaps both, so the user can choose performance or convenience?
void stack_init(struct stack *);
void stack_cleanup(struct stack *);
struct stack *stack_alloc(void); /* also calls stack_init on new stack */
void stack_free(struct stack *); /* calls stack_cleanup, then frees */
It's possible to do information hiding in C, whereby you can completely conceal from the client code (which uses the stack module) what a struct stack is.
However, if you provide a stack_init, then the client has to know how large a stack is, since it provides the memory for it. Generally, modules which completely hide an implementation also hide how large it is, and so provide only a stack_alloc and stack_free type interface.
An advantage of that is that client code doesn't have to be recompiled if the stack module is changed and the structure is larger. This is very good if you're writing a widely-used library: it is easy for users to upgrade or possibly downgrade.
However, revealing the implementation allows for more efficient code, since the client has the freedom to choose memory management for stacks. Stacks can be declared as local variables in automatic storage ("on the stack", so to speak), statically as global variables, or packed into arrays.
The user can do things like:
{
struct stack temp_stack;
stack_init(&temp_stack); /* stack is good to go! */
/* ... use stack ... */
stack_cleanup(&temp_stack); /* don't forget to clean up */
}
and things like:
struct stack array_of_stacks[42];
int i;
for (i = 0; i < 42; i++)
stack_init(&array_of_stacks[i]); /* no memory allocation taking place */
All this code has a compile-time dependency of the definition of struct stack; whenever struct stack is touched, it must be recompiled.
Note that if the above struct stack definition is the exact definition for a stack (the only property of a stack is that it has a pointer to a top node which can be null) then, physically speaking, a struct stack * pointer is actually a pointer to a pointer. We can use a typedef name to write the code so that we can use either definition:
/* Alternative "A" */
typedef struct node *stack_t; /* a stack_t type is a pointer to a node */
/* Alternative "B" */
typedef struct stack {
struct node *top;
} stack_t; /* stack_t is a structure containing a pointer to a node */
Either way, the API in terms of stack_t then looks like this:
void stack_init(stack *s);
int stack_push(stack *s, int item);
or whatever. If stack is a pointer (alternative "A" above) then stack *s is a pointer-to-pointer, and so your code will be full of pointer-to-pointer manipulation.
If you're not comfortable with pointer-to-pointer syntax all over the place, then you can give yourself a macro to pretend that it's a structure anyway.
/* Alternative "A" */
typedef struct node *stack_t; /* a stack_t type is a pointer to a node */
#define stack_top(s) (*(s)) /* dereference stack s to obtain the top pointer */
/* Alternative "B" */
typedef struct stack {
struct node *top;
} stack_t; /* stack_t is a structure containing a pointer to a node */
#define stack_top(s) ((s)->top) /* dereference struct pointer to get top pointer */
In the code you can then do things like:
/* push new_node onto stack */
new_node->next = stack_top(s);
stack_top(s) = new_node;
If you consistently use the stack_top accessor, you can now flip the representation of the stack type between alternative "A" and "B" without rewriting any of your code (only recompiling it).
Some nit-picky C programmers will cringe at stack_top(s) = new_node since it looks like a function call is being assigned (which is impossible in C without using macros to bend the language), and prefer a "setter" function for that stack_top_set(s, new_node). That's mostly just outdated, parochial thinking.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int Item;
#define ItemFormat "%d"
struct node {
Item data;
struct node *next;
};
typedef struct node *Stack;
void push(Stack *st, Item x){
struct node *newnode = malloc(sizeof(struct node));
newnode->data = x;
newnode->next = *st;
*st = newnode;
}
bool isEmpty(Stack st){
return st == NULL;
}
Item pop(Stack *st) {
if(!isEmpty(*st)){
struct node *p = *st;
Item value = p->data;
*st = p->next;
free(p);
return value;
}
fprintf(stderr, "Stack is Empty!\n");
return (Item)0;
}
bool inputItem(Item *x){
int stat;
if(1==(stat=scanf(ItemFormat, x)))
return true;
if(stat == EOF)
return false;
scanf("%*[^\n]");
return false;
}
void printItem(Item x){
printf(ItemFormat, x);
}
int main(void){
Stack st = NULL, array[5] = { NULL };
Item x;
while(inputItem(&x)){
push(&array[1], x);
}
while(!isEmpty(array[1])){
x = pop(&array[1]);
printItem(x);
printf("\n");
}
/*
while(inputItem(&x)){
push(&st, x);
}
while(!isEmpty(st)){
x = pop(&st);
printItem(x);
printf("\n");
}
*/
return 0;
}
The static implemetation of two stacks in a single array in C looks something like this...the stack structure will have two top variables top1 and top2.
struct stack
{
int data[MAX];
int top1,top2;
}s;
top1 is initialized to -1 while top2 is initialized to MAX
Overflow condtitions:
1]
if((s->top1)+1==s->top2)
printf("Stack 1 overflow\n");
2]
if((s->top2)-1==s->top1)
printf("Stack 2 overflow\n");
The underflow conditions become pretty obvious. This method may not be memory efficient since we might run out of storage space in the array but it is the basic fundamentals of multiple stacks in a single array.
Related
While doing a coding exercise in C, I had to allocate memory for a pointer to a structure (cur), even though the structure presumably already had memory pre-allocated for it, otherwise I would get an 'assignment to null pointer' type of error.
I was under the assumption that if the pointer was going to point to a structure with pre-allocated memory, allocating further memory would be reduntant? To clarify, the code compiles and runs without errors, just confused as to why I needed to allocate memory to achieve the intended behavior.
/* create a stack */
typedef struct {
int top;
struct TreeNode array[MAX_ARR_SIZE];
} Stack;
int node_comparator(const void *p, const void *q);
struct TreeNode *increasingBST(struct TreeNode *root) {
/* add all the nodes to an array via DFT */
int i, sorted_pos = 0;
struct TreeNode *start, *cur;
struct TreeNode sorted_nodes[MAX_ARR_SIZE];
Stack *node_stack = malloc(sizeof(Stack));
node_stack->top = -1;
node_stack->array[++node_stack->top] = *root;
/* below is the pointer in question
* originally, this line was not here */
cur = malloc(sizeof(struct TreeNode));
while (node_stack->top != -1) {
/* "pop" node off stack */
*cur = node_stack->array[node_stack->top--];
/* add node to array */
sorted_nodes[sorted_pos++] = *cur;
/* add right and left node to stack, if present */
if (cur->right != NULL)
node_stack->array[++node_stack->top] = *cur->right;
if (cur->left != NULL)
node_stack->array[++node_stack->top] = *cur->left;
}
/* etc... */
Here's a link to a gist for full context. Thanks!
The extra memory isn't redundant since you want to save the node's details off the stack. However, you don't need to use malloc. You can declare cur at the top of your function (struct TreeNode cur;) and then use memcpy (from string.h).
memcpy(&cur,&node_stack->array[node_stack->top--],sizeof(cur));
Since cur is no longer a pointer, you would need to edit your code and replace occurrences of cur-> with cur..
I'm getting started with dynamic lists and i don't understand why it is necessary to use the malloc function even when declaring the first node in the main() program, the piece of code below should just print the data contained in the first node but if i don't initialize the node with the malloc function it just doesn't work:
struct node{
int data;
struct node* next;
};
void insert(int val, struct node*);
int main() {
struct node* head ;
head->data = 2;
printf("%d \n", head->data);
}
You don’t technically, but maintaining all nodes with the same memory pattern is only an advantage to you, with no real disadvantages.
Just assume that all nodes are stored in the dynamic memory.
Your “insert” procedure would be better named something like “add” or (for full functional context) “cons”, and it should return the new node:
struct node* cons(int val, struct node* next)
{
struct node* this = (struct node*)malloc( sizeof struct node );
if (!this) return next; // or some other error condition!
this->data = val;
this->next = next;
return this;
}
Building lists is now very easy:
int main()
{
struct node* xs = cons( 2, cons( 3, cons( 5, cons( 7, NULL ) ) ) );
// You now have a list of the first four prime numbers.
And it is easy to handle them.
// Let’s print them!
{
struct node* p = xs;
while (p)
{
printf( "%d ", p->data );
p = p->next;
}
printf( "\n" );
}
// Let’s get the length!
int length = 0;
{
struct node* p = xs;
while (p)
{
length += 1;
p = p->next;
}
}
printf( "xs is %d elements long.\n", length );
By the way, you should try to be as consistent as possible when naming things. You have named the node data “data” but the constructor’s argument calls it “val”. You should pick one and stick to it.
Also, it is common to:
typedef struct node node;
Now in every place except inside the definition of struct node you can just use the word node.
Oh, and I almost forgot: Don’t forget to clean up with a proper destructor.
node* destroy( node* root )
{
if (!root) return NULL;
destroy( root->next );
free( root );
return NULL;
}
And an addendum to main():
int main()
{
node* xs = ...
...
xs = destroy( xs );
}
When you declare a variable, you define the type of the variable, then it's
name and optionally you declare it's initial value.
Every type needs an specific amount of memory. For example int would be
32 bit long on a 32bit OS, 8 bit long on a 64.
A variable declared in a function is usually stored in the stack associated
with the function. When the function returns, the stack for that function is
no longer available and the variable does not longer exist.
When you need the value/object of the variable to exist even after a function
returns, then you need to allocate memory on a different part of the program,
usually the heap. That's exactly what malloc, realloc and calloc do.
Doing
struct node* head ;
head->data = 2;
is just wrong. You've declaring a pointer named head of type struct node,
but you are not assigning anything to it. So it points to an unspecified
location in memory. head->data = 2 tries to store a value at an unspecified
location and the program will most likely crash with a segfault.
In main you could do this:
int main(void)
{
struct node head;
head.data = 2;
printf("%d \n", head.data);
return 0;
}
head will be saved in the stack and will persist as long as main doesn't
return. But this is only a very small example. In a complex program where you
have many more variables, objects, etc. it's a bad idea to simply declare all
variables you need in main. So it's best that objects get created when they
are needed.
For example you could have a function that creates the object and another one
that calls create_node and uses that object.
struct node *create_node(int data)
{
struct node *head = malloc(sizeof *head);
if(head == NULL)
return NULL; // no more memory left
head->data = data;
head->next = NULL;
return head;
}
struct node *foo(void)
{
struct node *head = create_node(112);
// do somethig with head
return head;
}
Here create_node uses malloc to allocate memory for one struct node
object, initializes the object with some values and returns a pointer to that memory location.
foo calls create_node and does something with it and it returns the
object. If another function calls foo, this function will get the object.
There are also other reasons for malloc. Consider this code:
void foo(void)
{
int numbers[4] = { 1, 3, 5, 7 };
...
}
In this case you know that you will need 4 integers. But sometimes you need an
array where the number of elements is only known during runtime, for example
because it depends on some user input. For this you can also use malloc.
void foo(int size)
{
int *numbers = malloc(size * sizeof *numbers);
// now you have "size" elements
...
free(numbers); // freeing memory
}
When you use malloc, realloc, calloc, you'll need to free the memory. If
your program does not need the memory anymore, you have to use free (like in
the last example. Note that for simplicity I omitted the use of free in the
examples with struct head.
What you have invokes undefined behavior because you don't really have a node,, you have a pointer to a node that doesn't actually point to a node. Using malloc and friends creates a memory region where an actual node object can reside, and where a node pointer can point to.
In your code, struct node* head is a pointer that points to nowhere, and dereferencing it as you have done is undefined behavior (which can commonly cause a segfault). You must point head to a valid struct node before you can safely dereference it. One way is like this:
int main() {
struct node* head;
struct node myNode;
head = &myNode; // assigning the address of myNode to head, now head points somewhere
head->data = 2; // this is legal
printf("%d \n", head->data); // will print 2
}
But in the above example, myNode is a local variable, and will go out of scope as soon as the function exists (in this case main). As you say in your question, for linked lists you generally want to malloc the data so it can be used outside of the current scope.
int main() {
struct node* head = malloc(sizeof struct node);
if (head != NULL)
{
// we received a valid memory block, so we can safely dereference
// you should ALWAYS initialize/assign memory when you allocate it.
// malloc does not do this, but calloc does (initializes it to 0) if you want to use that
// you can use malloc and memset together.. in this case there's just
// two fields, so we can initialize via assignment.
head->data = 2;
head->next = NULL;
printf("%d \n", head->data);
// clean up memory when we're done using it
free(head);
}
else
{
// we were unable to obtain memory
fprintf(stderr, "Unable to allocate memory!\n");
}
return 0;
}
This is a very simple example. Normally for a linked list, you'll have insert function(s) (where the mallocing generally takes place and remove function(s) (where the freeing generally takes place. You'll at least have a head pointer that always points to the first item in the list, and for a double-linked list you'll want a tail pointer as well. There can also be print functions, deleteEntireList functions, etc. But one way or another, you must allocate space for an actual object. malloc is a way to do that so the validity of the memory persists throughout runtime of your program.
edit:
Incorrect. This absolutely applies to int and int*,, it applies to any object and pointer(s) to it. If you were to have the following:
int main() {
int* head;
*head = 2; // head uninitialized and unassigned, this is UB
printf("%d\n", *head); // UB again
return 0;
}
this is every bit of undefined behavior as you have in your OP. A pointer must point to something valid before you can dereference it. In the above code, head is uninitialized, it doesn't point to anything deterministically, and as soon as you do *head (whether to read or write), you're invoking undefined behavior. Just as with your struct node, you must do something like following to be correct:
int main() {
int myInt; // creates space for an actual int in automatic storage (most likely the stack)
int* head = &myInt; // now head points to a valid memory location, namely myInt
*head = 2; // now myInt == 2
printf("%d\n", *head); // prints 2
return 0;
}
or you can do
int main() {
int* head = malloc(sizeof int); // silly to malloc a single int, but this is for illustration purposes
if (head != NULL)
{
// space for an int was returned to us from the heap
*head = 2; // now the unnamed int that head points to is 2
printf("%d\n", *head); // prints out 2
// don't forget to clean up
free(head);
}
else
{
// handle error, print error message, etc
}
return 0;
}
These rules are true for any primitive type or data structure you're dealing with. Pointers must point to something, otherwise dereferencing them is undefined behavior, and you hope you get a segfault when that happens so you can track down the errors before your TA grades it or before the customer demo. Murphy's law dictates UB will always crash your code when it's being presented.
Statement struct node* head; defines a pointer to a node object, but not the node object itself. As you do not initialize the pointer (i.e. by letting it point to a node object created by, for example, a malloc-statement), dereferencing this pointer as you do with head->data yields undefined behaviour.
Two ways to overcome this, (1) either allocate memory dynamically - yielding an object with dynamic storage duration, or (2) define the object itself as an, for example, local variable with automatic storage duration:
(1) dynamic storage duration
int main() {
struct node* head = calloc(1, sizeof(struct node));
if (head) {
head->data = 2;
printf("%d \n", head->data);
free(head);
}
}
(2) automatic storage duration
int main() {
struct node head;
head.data = 2;
printf("%d \n", head.data);
}
In a project, I was asked to create an INT128 type using int32_t and make postfixed calculations with them. I was using a generic stack to keep track of the operands. The code is below:
typedef struct int128
{
int32_t byteArray[4];
} INT128;
typedef struct node{
void *value;
struct node *bottom;
} NODE;
typedef struct stack{
int size;
size_t dataType;
NODE *top;
} STACK;
I used memcpy() to copy the value of an INT128 to the stack and back. It worked well when the stack had only char variables, but the results were completely different with the INT128 type.
I'm not so familiar with memory manipulation, so theres probably something I'm not seeing here.
Thanks!
Edit:
Sorry guys...im using the functions below to push and pop data from the stack:
void push(STACK *machine,void *pushed)
{
NODE *newNode = malloc(sizeof(NODE));
newNode->value = malloc(machine->dataType);
memcpy(newNode->value,pushed,sizeof(machine->dataType));
newNode->bottom = machine->top;
machine->top = newNode;
machine->size++;
}
void pop(STACK *machine, void *poppedValue)
{
if(machine->top == NULL)
{
printf("WARNING: empty stack!\n");
}
else
{
NODE *popped = machine->top;
memcpy(poppedValue,popped->value,machine->dataType);
machine->top = popped->bottom;
free(popped->value);
free(popped);
machine->size--;
}
}
I'm initializing the stack like:
STACK *numStack = createStack(sizeof(INT128));
And using the push/pop functions normally.
There's a problem here:
newNode->value = malloc(machine->dataType);
memcpy(newNode->value,pushed,sizeof(machine->dataType));
You allocate machine->dataType bytes, but then you copy sizeof machine->dataType bytes. These may be different quantities, either causing a buffer overflow or causing bad behaviour due to not copying enough bytes.
I guess you probably meant to not use sizeof in the second line.
So I'm doing some linked list revison and Im trying to just load a list with some numbers and then print it out. Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack {
int data;
struct stack *next;
}*stack;
stack create_s(void){
stack s = (void*)malloc(sizeof(stack));
s->next = NULL;
return s;
}
void push_s(stack s, int data) {
while (s->next != NULL) {
s = s->next;
}
s->next = (void*)malloc(sizeof(stack));
s=s->next;
s->data = data;
s->next = NULL;
}
void print_s(stack s) {
if (s==NULL) {
return;
}
else {
while (s->next != NULL) {
printf("%d\n",s->data);
s=s->next;
}
}
}
int main (void) {
stack s = create_s();
push_s(s,2);
push_s(s,4);
push_s(s,6);
push_s(s,8);
print_s(s);
return 0;
}
My output is however:
-1853045587
2
4
6
when it should be
2
4
6
8
Is it printing the address of my struct at the beginning? Also, why is it not printing my last element?
Thanks
The code contains several errors, but the first thing that catches the eye is that your memory allocation is already obviously broken
stack s = (void*)malloc(sizeof(stack));
You defined stack as a pointer type. This means that sizeof(stack) evaluates to pointer size and the above malloc allocates enough space to store a single pointer, not enough for the entire struct stack object. The same memory allocation error is present in push_s as well.
Here's some advice
Don't hide pointer types behind typedef names. Define your stack as
typedef struct stack{
int data;
struct stack *next;
} stack;
and use stack * wherever you need a pointer. I.e. make that * visible instead of hiding it "inside" a typedef name. This will make your code easier to read.
Don't cast the result of malloc. Anyway, what is the point of casting it to void * when it is void * already???
Don't use sizeof with types unless you really really have to. Prefer to use sizeof with expressions. Learn to use the following malloc idiom
T *p = malloc(sizeof *p);
or, in your case
struct stack *s = malloc(sizeof *s);
This will allocate a memory block of appropriate size.
Also, as #WhozCraig noted in the comments, the very first node in your list is apparently supposed to serve as a "sentinel" head node (with undefined data value). In your code you never initialize the data value in that head node. Yet in your print_s function you attempt to print data value from the head node. No wonder you get garbage (-1853045587) as the first line in your output. Don't print the very first node. Skip it, if it really is supposed to serve as a sentinel.
Also, the cycle termination condition in print_s looks strange
while (s->next != NULL)
Why are you checking s->next for NULL instead of checking s itself? This condition will terminate the cycle prematurely, without attempting to print the very last node in the list. This is the reason why you don't see the last element (8) in your output.
The actual cause of the given output can be fixed by changing:
s=s->next;
s->data = data;
to
s->data = data;
s=s->next;
Trying to implement below code for some assignment but getting an error for malloc array generation "[Error] conflicting types for 'stack'" Any Help ??
Thanks in Advance.
#include<stdio.h>
#include<stdlib.h>
struct treenode
{
char info;
struct treenode *firstchild;
struct treenode *next;
int flag;
};
typedef struct treenode *NODEPTR;
NODEPTR *stack;
// Trying to create array here
stack=(NODEPTR*)malloc(sizeof(NODEPTR)*20);
int main()
{
printf("YO\n");
return 0;
}
EDIT :
I can't move it to main , as i have to access the stack globally in different functions.
because Stack array gets destroyed when it go to another function.
check here http://ideone.com/5wpZsp ,
When i give static declaration globally it works smoothly, here : http://ideone.com/3vx9fz
You can not call assignment operations at global scope. Try malloc operation in main() instead.
And the type of stack is not a pointer but pointer to pointer. Are you sure about it's declaration ?
Move your initialization of stack to inside of the main method.
EDIT An example showing how the malloc data can persist to other function calls even though malloc is called inside of main.
#include<stdio.h>
#include<stdlib.h>
struct treenode
{
char info;
struct treenode *firstchild;
struct treenode *next;
int flag;
};
typedef struct treenode *NODEPTR;
NODEPTR *stack;
void test_stack()
{
printf("%p\n", stack);
printf("%d\n", stack[19]->flag);
}
int main()
{
// Trying to create array here
stack=(NODEPTR*)malloc(sizeof(NODEPTR)*20);
stack[19] = (NODEPTR*)malloc(sizeof(struct treenode));
stack[19]->flag = 42;
test_stack();
return 0;
}
Step 1: Move the declaration of stack inside main. There's no reason it should be declared globally:
int main( void )
{
NODEPTR *stack;
...
Step 2: Move the malloc call inside main (you cannot perform an assignment or a function call outside of a function).
Step 3: Drop the cast; it's unnecessary1 and just adds visual clutter.
Step 4: Use sizeof *stack as opposed to sizeof (NODEPTR) in the argument to malloc:
stack = malloc( sizeof *stack * 20 );
The result is the same, but this is easier to read, and avoids maintenance headaches if you ever change the type of stack.
Step 5: free your stack when you're done. Yeah, for this program it doesn't matter, but it's a good habit to get into.
So after all this, your code should read:
int main( void )
{
NODEPTR *stack;
stack = malloc( sizeof *stack * 20 );
...
free( stack );
return 0;
}
Stylistic nit: Hiding pointer types behind typedefs is bad juju IME. Pointer semantics are important, and if the programmer is ever expected to dereference an object of type NODEPTR (either explicitly, as (*node).info, or implicitly, as node->info), then it's usually best to declare that object using pointer declaration syntax, something like
typedef struct treenode Node;
Node *node;
Node **stack;
...
stack[i]->next = node->next;
etc. so the person using your types knows exactly how many levels of indirection are involved and can write their code accordingly (multiple indirection is not hard). If the type is meant to be truly opaque and never directly dereferenced, but just passed around to an API that handles all that, then hiding the pointerness of that type is okay. Otherwise, leave it exposed.
I tend not to typedef struct types for a similar reason, but I suspect I'm an outlier in that regard.
Ahd who broke the code formatter?!
1 - In C, that is; in C++, the cast is required, but if you're writing C++, you should be using new instead of malloc anyway.
#include<stdio.h>
#include<stdlib.h>
struct treenode
{
char info;
struct treenode *firstchild;
struct treenode *next;
int flag;
};
typedef struct treenode *NODEPTR;
NODEPTR *stack;
int main()
{
stack=malloc(sizeof(NODEPTR)*20);
printf("YO\n");
return 0;
}
This will work.
allocate memory inside(malloc) your main.
There is no need to typecast out put of malloc. for further info see this post
EDIT :
In your comment you mentioned that memory will be destroyed when you move other function.
This is not true. Once you allocate memory using malloc it will not be destroyed until you call free().
So if you want to access the malloc'ed variable in other function pass the variable as argument to other function.
See this example program below
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
char *str;
void passMalloc(char **str);
int main()
{
str = malloc(100 * sizeof(char));
strcpy(str, "GoodMorning");
printf("\nMain before pass : %s\n", str);
passMalloc(&str);
printf("Main after pass : %s\n\n", str);
free(str);
return 0;
}
void passMalloc(char **str)
{
strcpy(*str, "GoodEvening");
printf("Function Def : %s\n", *str);
}