Trying to implement a stack using dynamic array.
The Problem which i am facing is that if i a pushing 60 or 90 elements then the program is running fine but on inserting say 600 elements while printing the first two elements are showing junk value.

Compiled the code using DEVc++ and Codelite (both using GCC compiler)
In Codelite if i am trying to debug the number of junk values in the output increase.

#include <stdio.h>
#include <malloc.h>

#define INCREMENT 30

//int *array;
int capacity = 0;
int size = 0;//this will also be used as a index

int push(int *array,int val)
{
	array[size++] = val;
	if(size == capacity)
		capacityUP(array,capacity+INCREMENT);
	
	return 1;
}

int pop(int *array)
{
	size-=1;//index is one less than the size
	if(size < 0)
		return 0;
	else
		return array[size];
}

int capacityUP(int *array,int ncapacity)
{
	int i ;
	realloc(array,sizeof(int)*ncapacity);
	capacity = ncapacity;
	printf("increasing capacity to %d \n",capacity);
	
 	return 1;
}

int capacityDown();
main()
{
	int i;
	int *array = (int*)malloc(sizeof(int) * INCREMENT);
	capacity = INCREMENT;
	
	for(i = 0 ; i < 600 ; i++)
		push(array,i);
	
	printf("size is %d \n",size);
	do
	{
		printf("poping the top %d \n", pop(array));
	}while(size);
	printf("size is %d \n",size);
	getchar();
	
}

The problem has to do with modifying a copy of the pointer. Pointers work the same way when it comes to passing by reference as everything else. If you want to change what the pointer points to, another level of indirection is needed. Why? Because *everything* is passed by value in C. Pass by reference is only faked by using pointers and indirection. The pointer is passed by value, but the pointed to object can still be reached by dereferencing the pointer.

This sample shows the problem.

#include <stdio.h>
#include <stdlib.h>

void change_pointer(char *p)
{
    /* Changing a *copy* of the original pointer */
    p = (char*)malloc(1);
    printf("After change: %p\n", (void*)p);
}

int main()
{
    char *p = (char*)malloc(1);

    printf("Before change: %p\n", (void*)p);
    change_pointer(p);

    /* The original pointer is unchanged */
    printf("After return: %p\n", (void*)p);

    return 0;
}

This sample fixes the problem by passing a pointer to the pointer.

#include <stdio.h>
#include <stdlib.h>

void change_pointer(char **p)
{
    /* Indirection to the original pointer */
    *p = (char*)malloc(1);
    printf("After change: %p\n", (void*)*p);
}

int main()
{
    char *p = (char*)malloc(1);

    printf("Before change: %p\n", (void*)p);
    change_pointer(&p);

    /* The original pointer is changed!. Yay indirection! */
    printf("After return: %p\n", (void*)p);

    return 0;
}

And finally, this is your code with that same change made. Edward did not fix anything else except stuff needed to compile the code on Visual C++ 2010. Improving the code is a lesson for another thread. :)

#include <stdio.h>
#include <malloc.h>

#define INCREMENT 30

//int *array;
int capacity = 0;
int size = 0;//this will also be used as a index

int capacityUP(int **array,int ncapacity)
{
	*array = (int*)realloc(*array,sizeof(int)*ncapacity);
	capacity = ncapacity;
	printf("increasing capacity to %d \n",capacity);
	
 	return 1;
}

int capacityDown();

int push(int **array,int val)
{
	(*array)[size++] = val;
	if(size == capacity)
		capacityUP(array,capacity+INCREMENT);
	
	return 1;
}

int pop(int **array)
{
	size-=1;//index is one less than the size
	if(size < 0)
		return 0;
	else
		return (*array)[size];
}

int main()
{
	int i;
	int *array = (int*)malloc(sizeof(int) * INCREMENT);
	capacity = INCREMENT;
	
	for(i = 0 ; i < 600 ; i++)
		push(&array,i);
	
	printf("size is %d \n",size);
	do
	{
		printf("poping the top %d \n", pop(&array));
	}while(size);
	printf("size is %d \n",size);
	getchar();
	
}

Edited 6 Years Ago by Radical Edward: n/a

Comments
Concise and To the mark reply, Thanks Edward
This question has already been answered. Start a new discussion instead.