Properly Reading a Char from an Int in C on a Stack - c

so I'm having a crazy time right now reading characters off a stack. I'm storing the char as an int, so I can check for the EOF signal, but things aren't going so well. I'm new to the implementation of stacks, so things are probably just wrong somewhere. Here's my code.
I'm getting both the incorrect top character on the stack (it shows -1, which is EOF, instead of the last character entered), as well as some sort of memory error - "pointer being freed was not allocated", which references the destroyStack() function.
int main( void ) {
int *letter;
STACK *stack;
stack = createStack();
letter = (int *) malloc( sizeof( int ) );
printf("Please enter the letters, each on a new line, or to quit:\n");
while ( *letter != EOF || stackFull( stack ) ) {
*letter = getchar();
if ( *letter != '\n' && *letter != ' ' && *letter != EOF ) {
printf("Adding %c to the stack.\n", *letter);
pushStack( stack, letter );
}
}
free( letter );
printf("Stack count is %i\n", stackCount(stack));
letter = (int *) getStackTop( stack );
printf("The top char is %i\n", *letter);
destroyStack( stack );
return 0;
}
and my stack code:
typedef struct node {
void *dataPointer;
struct node *link;
} NODE;
typedef struct {
int count;
NODE *top;
} STACK;
STACK* createStack() {
STACK *stack;
stack = (STACK *) malloc( sizeof( STACK ) );
if ( stack ) {
stack->count = 0;
stack->top = NULL;
}
return stack;
}
bool pushStack( STACK *stack, void *pointerToData) {
NODE *newNode;
newNode = (NODE *) malloc( sizeof( NODE ) );
if ( !newNode ) {
return false;
}
newNode->dataPointer = pointerToData;
newNode->link = stack->top;
stack->top = newNode;
( stack->count )++;
return true;
}
void* popStack( STACK *stack ) {
void* topData;
NODE* temp;
if ( stack->count == 0 ) {
topData = NULL;
} else {
temp = stack->top;
topData = stack->top->dataPointer;
stack->top = stack->top->link;
free( temp );
( stack->count )--;
}
return topData;
}
void* getStackTop( STACK *stack ) {
if ( stack->count == 0 ) {
return NULL;
} else {
return stack->top->dataPointer;
}
}
bool stackEmpty( STACK *stack ) {
return ( stack->count == 0 );
}
bool stackFull( STACK *stack ) {
NODE *temp;
if ( ( temp = (NODE *) malloc( sizeof( *(stack->top) ) ) ) ) {
free( temp );
return false;
}
return true;
}
int stackCount( STACK *stack ) {
return ( stack->count );
}
STACK* destroyStack( STACK *stack ) {
NODE *temp;
if ( stack ) {
while ( stack->top != NULL ) {
free( stack->top->dataPointer );
temp = stack->top;
stack->top = stack->top->link;
free( temp );
}
free( stack );
}
return NULL;
}

Your problem is with letter. It's only allocated once and when you push it onto the stack, it doesn't make a copy. That's why your top data pointer is always the last thing you pushed. Then you free it and destroyStack frees it and you get another error. Since the stack functions were from your assignment, the fix is to allocate a new data pointer inside the loop every iteration and ensure that it's not freed outside of destroyStack.

Well . . . it looks like you're double-freeing the data pointer:
pushStack( stack, letter );
...
free( letter );
...
free( stack->top->dataPointer ); //(in destroyStack)
So, I would start by removing the free( letter ) line.

Look at how many int sized pieces of memory you've allocated. I think you'll need to allocate a new one for each entry you push onto the stack.

Related

How to fix conditional jump?

I have a problem with, i think, function INPUT. But i can't understand how to fix it
[functions code]
typedef struct Item {
int data;
struct Item* next;
} Item;
typedef struct Queue{
Item* head;
Item* tail;
} Queue;
void input(Queue* list,int* stroka) {
Item* new = (Item*)malloc(sizeof(Item));
new->data = *stroka;
new->next = NULL;
if (!list->head) {
list->head = new;
list->tail = new;
} else {
list->tail->next = new;
list->tail = new;
}
}
int main() {
int stroka;
Queue* list = (Queue*)malloc(sizeof(Queue));
while(stroka != EOF) {
stroka = getchar();
input(list, &stroka);
}
printf("\n");
print(list);
}
[valgrind message]
Conditional jump or move depends on uninitialised value(s)
==29969== at 0x10931A: input ()
==29969== by 0x1093CF: main ()
==29969== Uninitialised value was created by a heap allocation
==29969== at 0x48427B5: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==29969== by 0x1093B1: main ()
tried to change some blocks of code but i didn't come to anything
In the while loop you are using an uninitialized object of the type int and trying it to compare with a null pointer
int stroka;
Queue* list = (Queue*)malloc(sizeof(Queue));
while(stroka != EOF) {
stroka = getchar();
input(list, &stroka);
}
that does not make sense.
And there is no need to allocate dynamically an object of the type Queue.
Also instead of getchar it is much better to use scanf to enter integers instead of single characters that will be interpreted as integers including the new line character '\n'..
Also there is no any sense to pass the object stroke through a pointer to the function.
The function should be declared and defined the following way
int input( Queue* list, int data )
{
Item *new_item = malloc( sizeof( *new_item ) );
int success = new_item != NULL;
if ( success )
{
new_item->data = data;
new_item->next = NULL;
if ( list->head == NULL )
{
list->head = new_item;
}
else
{
list->tail->next = new_item;
}
list->tail = new_item;
}
return success;
}
And in main you can write for example
int main( void )
{
Queue list = { .head = NULL, .tail = NULL };
for ( int data; scanf( "%d", &data ) == 1; )
{
input( &list, data );
}
printf("\n");
print(list);
}
If you want to enter characters then declare the function like
int input( Queue* list, char data );
and in main write
for ( char data; scanf( " %c", &data ) == 1; )
{
input( &list, data );
}
Pay attention to the space in the format string in the call of scanf. It allows to skip white space characters.
And do not forget to write a function that will free all the allocated memory when the list will nit be required any more.

Adding items to a linked list

I'd like to add an element to a list of element. My list is a struct containing a double, an integer and a pointer to the next element. Could someone tell me how to do the Add function please
#include <stdio.h>
#include <stdlib.h>
typedef struct Liste Liste;
struct Liste{
double c;
int n;
Liste* next; // pointe sur l'élément suivant
};
void Add(Liste array, Liste item) {
Liste* last = array.next;
while (last != NULL) {
last = last->next;
}
array.next = &item;
printf("%p\n", array.next);
}
int main(){
Liste array = {12.4, 4, NULL};
printf("%f\n", array.c);
Liste item = {15.4, 7, NULL};
Add(array, item);
printf("%p\n", array.next);
return 0;
}
Pass-by-value
In Add, C makes a copy of all the function parameters; their scope is the function itself. When one returns, the function parameters are popped from the stack and there is no way to get them back, as you have seen. The way to mutate structures is to pass a pointer to the structure, then modify that pointer using the structure pointer dereference operator, (arrow ->.)
Design
The reason one would use a linked-list is it is very cheap to reorder it, but the head of your linked-list is fixed, so you can't change it. You might change this by delineating the container, the list itself, from the contents. This is similar to using a double-pointer, but I think less confusing.
struct Noeud {
double c;
int n;
struct Noeud* next; // pointe sur l'élément suivant
};
struct Liste {
struct Noeud *tete; // singly-linked-list est defini par un pointer seul
};
Then you can add, (I've included assert.h.)
/* `O(n)` */
static void AddQueue(struct Liste *liste, struct Noeud *item) {
assert(liste && item && item->next == NULL);
struct Noeud* last = liste->tete;
if(last == NULL) { // case spécieux
liste->tete = item;
} else {
while (last->next != NULL) {
last = last->next;
}
last->next = item;
}
}
However, it's much simpler and asymptotically faster to add at the beginning of the list.
Pointerstructures like a linked list are powerful tools with a wide rage of application.
But first you have to understand pointers.
A pointer is a datastructure which contains the address of a datastructure.
Whenever you call a function the arguments of it are copied (pushed) to the stack.
If the arguments require a lot of storage space you use a pointer instead.
the code below uses pointers to create a linked list
#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
typedef struct List List;
struct List{
double c;
int n;
List *next;
};
void AddItemEnd( List *RootItem, List *Item )
{
List *Last = RootItem;
while( Last->next != NULL )
{
Last = Last->next;
}
Last->next = Item;
}
void AddItemAtPos( List *RootItem, List *Item, unsigned int Pos )
{
if( Pos == 0 )
{
Item->next = RootItem;
}
else
{
List *TempItem = RootItem;
for( unsigned int i = 1; i < Pos && TempItem->next != NULL; ++i )
{
TempItem = TempItem->next;
}
Item->next = TempItem->next;
TempItem->next = Item;
}
}
void RemoveItemAtPos( List *RootItem, unsigned int Pos )
{
if( Pos == 0 )
{
free( (void*) RootItem );
}
else
{
List *TempItem = RootItem;
for( unsigned int i = 1; i < Pos && TempItem->next != NULL; ++i )
{
TempItem = TempItem->next;
}
if( TempItem->next == NULL )
{
return;
}else if( TempItem->next->next != NULL )
{
List *ItemToDelete = TempItem->next;
TempItem->next = TempItem->next->next;
free( (void*) ItemToDelete );
}else
{
free( (void*) TempItem->next );
TempItem->next =NULL;
}
}
}
int main(void) {
List *RootItem = malloc( sizeof( List ));
RootItem->c = 12.4;
RootItem->n = 4;
RootItem->next = NULL;
List *Item1 = malloc( sizeof(List ));
Item1->c = 15.4;
Item1->n = 7;
Item1->next = NULL ;
AddItemEnd( RootItem, Item1 );
List *IterationItem;
printf( "List created with AddItemEnd()\n\n" );
for( IterationItem = RootItem; IterationItem != NULL; IterationItem = IterationItem->next )
{
printf( "c: %lf\nn: %d\n\n", IterationItem->c, IterationItem->n );
}
List *item2 = malloc( sizeof( List ));
item2->c = 23.4;
item2->n = 1846;
item2->next = NULL ;
AddItemAtPos( RootItem, item2, 1 );
printf( "\n\nList extended with AddItemAtPos()\n\n");
for( IterationItem = RootItem; IterationItem != NULL; IterationItem = IterationItem->next )
{
printf( "c: %lf\nn: %d\n\n", IterationItem->c, IterationItem->n );
}
RemoveItemAtPos(RootItem, 1 );
printf( "\n\nList after RemoveItemAtPos()\n\n");
for( IterationItem = RootItem; IterationItem != NULL; IterationItem = IterationItem->next )
{
printf( "c: %lf\nn: %d\n\n", IterationItem->c, IterationItem->n );
}
free( (void*) RootItem );
free( (void*) item2 );
return 0;
}
The key elements when dealing with lists is pointers
and using memory allocation.
If we disregard your add function and just do a simple
example you will probably get the geist of it.
First allocate you starting list like this
Liste* array = malloc(sizeof(Liste));
Now you have one uninitialized block of memory
that array points to. You then need to initialize
it.
array->c = 12.4;
array->n = 4;
array->next = NULL;
in order to add a new entry to your list you
need to again allocate memory for the next node and
initialize it plus set the previous node next pointer
to point to it i.e. array->next.
Liste* item = malloc(sizeof(Liste));
item->c = 15.4;
item->n = 7;
item->next = NULL;
array->next = item;
now you have a list of two elements where array points
to the first
printing your short list
Liste* p = array;
while (p != NULL)
{
printf("%lf %d %p\n", p->c, p->n, p->next);
p = p->next;
}
So your Add functions does not allocate memory and copies
the parameters so that is not going to work.
Your Add function should have a pointer either to either the first or last item in your list e.g.
void Add(Liste* start, double c, int n)
Then you do as I showed you above and create a new node and assign the values
If you want to be able to pass an empty list to Add then you need to do differently, since start is copied it cannot be changed, you need to pass the address of the pointer
void Add(List** start, double c, int n)
{
Liste* node = malloc(sizeof(Liste));
...
(* put node in the list *)
if (*start == NULL)
{
*start = node; // first
}
else
{
(* find last node, see print loop *)
(* once you have last item, set it to point to node)
}
...
}
int main()
{
Liste* start = NULL;
Add(&start, 12.4, 4);
Add(&start, 15.4, 7);
...

Pop works only once in specific function

I implemented stack as linked list and I wanted to make function which tells if brackets are in good order for example : (()) is good ())( is bad . Logic of function isn't good right now but I don't know why pop() works only once.Here is my code(stog is stack and sljedeci is next):
struct stog {
int x;
stog *sljedeci;
};
typedef struct stog stog;
stog *top;
char pop() {
stog *temp;
temp = (stog*)malloc(sizeof(stog));
temp = top;
char n = temp->x;
top = temp->sljedeci;
top->x = temp->sljedeci->x;
free(temp);
return n;
}
void init() {
top = NULL;
}
void push(char x) {
stog *temp;
temp=(stog*)malloc(sizeof(stog));
temp->x = x;
temp->sljedeci = top;
top = temp;
}
void Brackets(const char* msg) {
char z;
for (int i = 0; i < strlen(msg); i++) {
if (msg[i] == '(') {
push('(');
}
if (msg[i]==')'){
z = pop();
printf("Bad\n");
}
}
}
int main() {
const char* msg = "(())";
init();
Brackets(msg);
return 0;
}
Output is:
Bad
It should be:
Bad
Bad
EDIT: Added init() and push() functions
This line in pop doesn't make sense:
top->x = temp->sljedeci->x;
In the prior line, you assign temp->sljedeci to top. So the x member referenced here is actually the same one on both sides, so assuming both top and temp->sljedeci are not null it does nothing. If either one is NULL, you invokes undefined behavior because you derefrence a null pointer. So get rid of this line.
You also have a memory leak here in pop:
temp = (stog*)malloc(sizeof(stog));
temp = top;
You allocate memory and assign its address to temp, but then you immediately overwrite that address with the value of top.
There's no need to allocate more memory here, so remove the malloc call.
We, beginners, should help each other.:)
I am doing your assignment the first time in my life.:)
For starters always use English words for identifiers. Otherwise a program text can be unreadable.
It is unclear why the data member x has the type int instead of char though the stack deals with characters of a string.
struct stog {
int x;
stog *sljedeci;
};
You did not show all your stack implementation nevertheless for example the function pop is invalid. It produces a memory leak.
At first you allocated memory and its address assigned to the pointer temp and at once in the next line you reassigned the pointer. So the allocated memory will not be freed.
temp = (stog*)malloc(sizeof(stog));
temp = top;
This statement
top->x = temp->sljedeci->x;
can invoke undefined behavior if top is equal to NULL.
Also in the function Brackets this if statement
if (msg[i]==')'){
z = pop();
printf("Bad\n");
}
does not make sense. The function will always output "Bad" as soon as the character ')' is encountered.
Here is a solution I have done.
#include <stdio.h>
#include <stdlib.h>
struct stack
{
char c;
struct stack *next;
};
char * top( struct stack **stack )
{
return *stack == NULL ? NULL : &( *stack )->c;
}
int push( struct stack **stack, char c )
{
struct stack *current = malloc( sizeof( struct stack ) );
int success = current != NULL;
if ( success )
{
current->c = c;
current->next = *stack;
*stack = current;
}
return success;
}
void pop( struct stack **stack )
{
if ( *stack )
{
struct stack *current = *stack;
*stack = ( *stack )->next;
free( current );
}
}
int empty( struct stack **stack )
{
return *stack == NULL;
}
void clear( struct stack **stack )
{
while ( *stack ) pop( stack );
}
int bracket_balance( const char *s )
{
struct stack *stack = NULL;
int balanced = 1;
for ( ; *s && balanced; ++s )
{
if ( *s == '(' )
{
push( &stack, *s );
}
else if ( *s == ')' )
{
if ( ( balanced = !empty( &stack ) && *top( &stack ) == '(' ) )
{
pop( &stack );
}
}
}
balanced = balanced && empty( &stack );
clear( &stack );
return balanced;
}
int main(void)
{
const char * s[] =
{
"", "(", ")", "()", ")(", "( ( ) )", "( )( )", "( ) ) (", "Hello"
};
for ( size_t i = 0; i < sizeof( s ) / sizeof( *s ); i++ )
{
if ( bracket_balance( s[i] ) )
{
printf( "\"%s\" has balanced brackets\n", s[i] );
}
else
{
printf( "\"%s\" does not have balanced brackets\n", s[i] );
}
}
return 0;
}
The program output is
"" has balanced brackets
"(" does not have balanced brackets
")" does not have balanced brackets
"()" has balanced brackets
")(" does not have balanced brackets
"( ( ) )" has balanced brackets
"( )( )" has balanced brackets
"( ) ) (" does not have balanced brackets
"Hello" has balanced brackets

a nested struct with pointers

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node *tree_ptr;
typedef struct table * Table;
struct node
{
char* element;
tree_ptr left, right;
};
typedef struct table
{
tree_ptr head;
int tree_h;
}table;
char* key = NULL;
Table insert(char* insert_key,Table t)
{
int height = 0;
//tree_ptr ptr = t->head;
tree_ptr *ptr = &(t->head);
key = strdup(insert_key);
tree_ptr new_node = malloc(sizeof(struct node));
new_node->element = key;
new_node->left = NULL;
new_node->right = NULL;
if ( t->head==NULL ){
*ptr = new_node;
t->tree_h = 0;
printf("head:%s\n",t->head->element);
return t;
}
while(1){
if ( strcmp(insert_key, (*ptr)->element)<0 ){
if ( (*ptr)->left ==NULL ){
(*ptr)->left = new_node;
height++;
if ( height > t->tree_h)
t->tree_h = height;
break;
}
else{
(*ptr) = (*ptr)->left;
height++;
}
}
else if ( strcmp(insert_key, (*ptr)->element)>0 ){
if ( (*ptr)->right ==NULL ){
(*ptr)->right = new_node;
height++;
if ( height > t->tree_h)
t->tree_h = height;
break;
}
else{
(*ptr) = (*ptr)->right;
height++;
}
}
else break;
}
return t;
}
int main() {
Table t = malloc(sizeof(table));
t->head = NULL;
t = insert("one", t);
t = insert("two", t);
t = insert("three", t);
printf("%s\n",t->head->element);
return 0;
}
The above is a simplified program, some definition code is given, so I could not change the basic structure, like table, Table, node, tree_ptr, while others could be changed.
What I am trying to implement is a spellchecking, the table stored the head of the tree and some other properties of the tree(which is omitted here), the tree is implemented as an ordered binary tree.
I find that, insert() works well up to two times, after the (*ptr) = (*ptr)->right; the t->head is changed as well. So after using it two times, I lost the head of the tree.
How to modify my insert()?
To insert a node into a tree you first have to search for an empty leaf. Apart from this you do not modify t, so there is no need of writing it back by return value:
void insert( char* insert_key, Table t )
{
// serach empty leaf, where to insert the new node
tree_ptr *ptr = &(t->head); // start at head
while ( *ptr != NULL ) // end if empty leaf is found
{
int cmpRes = strcmp( insert_key, (*ptr)->element );
if ( cmpRes == 0 )
return; // insert_key already is member of tree
if ( cmpRes < 0 )
ptr = &((*ptr)->left); // step down to left child
else
ptr = &((*ptr)->right); // step down to right child
}
// create new node
tree_ptr new_node = malloc( sizeof(struct node) );
new_node->element = strdup( insert_key );
new_node->left = NULL;
new_node->right = NULL;
// place new node at empty leaf
*ptr = new_node;
}
With this recursive function you can print your tree:
void printTree( tree_ptr ptr )
{
if ( ptr == NULL )
return;
printTree( ptr->left );
printf( "%s\n", ptr->element );
printTree( ptr->right );
}
printTree( t->head );
And with this one you can free all nodes of your tree:
void deleteTree( tree_ptr ptr )
{
if ( ptr == NULL )
return;
deleteTree( ptr->left );
deleteTree( ptr->right );
free( ptr );
}
deleteTree( t->head );
t->head = NULL;
The problem is ptr is pointing to the address of the pointer to a struct node, instead of directly pointing to a struct node:
tree_ptr *ptr = &(t->head);
Then when iterating in the while loop, you aren't changing the pointer ptr, but the pointer it is pointing to, which is t->head:
(*ptr) = (*ptr)->left;
This overwrites the pointer, t->head on every iteration, effectively erasing the nodes that pointer pointed to, and leaking memory.
Instead use a normal pointer to the struct node:
struct node* iter = t->head;
...
if ( strcmp(insert_key, iter->element)<0 ){
...
}
else{
iter = iter->left;
....
And I would highly suggest removing those typedefs that hide the pointer, because they make the code hard to read and obfuscate the types, which is not desirable in this context:
typedef struct node *tree_ptr;
typedef struct table * Table;
Also note that if the loop finds a duplicate, the allocated node is not freed, leaking the memory.

working with stack in C

I am trying to implement the following functionality
It takes a line of string as input and then tokenizes them and put them in a stack and later on it prints the buffer reverse
"welcome to the den"
whould show up as
den the to welcome
the problem with what I have so far is that it stops working and after debugging I realize that in the push function called in the main , the value of the token is not getting passed to the function .
Can any one please help me with why it does not pass the string of token to the push function .
I think there is some thing wrong with "char* data;" in the struct
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// self-referential structure
struct stackNode
{
char* data;
struct stackNode *pNext;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
// function prototypes
void push( StackNodePtr *pTop, char value );
//int pop( StackNodePtr *pTop );
//int isEmpty( StackNodePtr pTop );
void printStack( StackNodePtr pCurrent );
int main( void )
{
char *pToken = NULL;
int counter;
char input[BUFFER_SIZE];
StackNodePtr pStack = NULL;
printf("Please enter a line of text here :\n");
gets(input);
pToken = strtok(input, " ");
while(pToken != NULL)
{
push(&pStack, pToken);
printf("%p '%s'\n", pToken, pToken);
pToken = strtok(NULL, " ");
}
printf("I am out of while loop");
printStack(pStack);
return 0;
}
// Insert a node at the stack top
void push( StackNodePtr *pTop, char* value )
{
StackNodePtr pNew;
pNew = malloc( sizeof( StackNode ) );
if ( pNew != NULL )
{
pNew->data = value;
pNew->pNext = *pTop; // insert at top of stack
*pTop = pNew;
}
else
{
printf( "%d not inserted. No memory available.\n", value );
}
}
// output stack contents to the console
void printStack( StackNodePtr pCurrent )
{
if ( pCurrent == NULL )
{
printf( "The stack is empty.\n\n" );
}
else
{
printf( "The stack is:\n" );
while ( pCurrent != NULL )
{
printf( "%s", pCurrent->data );
pCurrent = pCurrent->pNext; // move to next element
}
printf( "NULL\n\n" );
}
}
This works:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_SIZE 256
// self-referential structure
struct stackNode
{
char* data;
struct stackNode *pNext;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
// function prototypes
void push(StackNodePtr* pTop, char* value);
//int pop( StackNodePtr *pTop );
//int isEmpty( StackNodePtr pTop );
void printStack( StackNodePtr pCurrent );
int main( void )
{
char *pToken = NULL;
int counter;
char input[BUFFER_SIZE];
StackNodePtr pStack = NULL;
printf("Please enter a line of text here :\n");
gets(input);
pToken = strtok(input, " ");
while(pToken != NULL)
{
push(&pStack, pToken);
printf("%p '%s'\n", pToken, pToken);
pToken = strtok(NULL, " ");
}
printf("I am out of while loop");
printStack(pStack);
return 0;
}
// Insert a node at the stack top
void push( StackNodePtr* pTop, char* value )
{
StackNodePtr pNew;
pNew = (StackNode*)malloc( sizeof( StackNode ) );
if ( pNew != NULL )
{
pNew->data = value;
pNew->pNext = *pTop; // insert at top of stack
*pTop = pNew;
}
else
{
printf( "%s not inserted. No memory available.\n", value );
}
}
// output stack contents to the console
void printStack( StackNodePtr pCurrent )
{
if ( pCurrent == NULL )
{
printf( "The stack is empty.\n\n" );
}
else
{
printf( "The stack is:\n" );
while ( pCurrent != NULL )
{
printf( "%s", pCurrent->data );
pCurrent = pCurrent->pNext; // move to next element
}
printf( "NULL\n\n" );
}
}
Input:
welcome to the den
Output:
0x7fff31d13fc0 'welcome'
0x7fff31d13fc8 'to'
0x7fff31d13fcb 'the'
0x7fff31d13fcf 'den'
I am out of while loopThe stack is:
denthetowelcomeNULL
I really only modified the code to compile on a reasonable machine. Just make sure you aren't printing character arrays as decimal types. I didn't fix any other issues, so no guarantees, just that THIS bit compiles and runs. I'm assuming you are going to add onto it later. Just make sure you are tracking your memory allocations.
I suspect the main problem is the mismatch between the prototype for push and it's definition.
void push( StackNodePtr *pTop, char value );
Vs
void push( StackNodePtr *pTop, char *value )
When I tried to compile the original it would not even compile, but maybe some broken would compile it and perhaps ignore the definition.
Here is a working version with the only change being to assign the declaration with the definition. Note that there are a shedload of warnings - you should address these as well.

Resources