Search code examples
cstack

C program giving error on debugging- ntdll!RtlRegisterSecureMemoryCacheCallback ()


I tried to implement a stack of integers in C by overriding a void pointer using functions. The code works fine for the most part, but gives the error on debugging when I free the allocated memory including the stack object and the integer array. I get this error :- ntdll!RtlRegisterSecureMemoryCacheCallback () from C:\WINDOWS\SYSTEM32\ntdll.dll. I use gcc on windows and vscode.

stack.h :-

#ifndef STACK_H 
#define STACK_H 

void stack_init(void**); 
void stack_push(void**,int); 
void stack_pop(void**); 
int stack_top(void*); 
int stack_empty(void*); 
int stack_size(void*); 
void stack_delete(void**);

#endif 

stack.c :-

#include"stack.h" 
#include<stdlib.h> 

typedef struct 
{
    int*arr; 
    int size; 
    int capacity; 
    int empty; 
}stack; 

void stack_init(void**self) 
{
    if(!*self) 
    {
        *self=malloc(sizeof(stack)); 
        ((stack*)(*self))->size=0;
        ((stack*)(*self))->capacity=1; 
        ((stack*)(*self))->arr=(int*)malloc(sizeof(int)*((stack*)(*self))->capacity); 
        ((stack*)(*self))->empty=1; 
    }
    return;
}

void _realloc(stack**self,int Buffer_size)  
{
    (*self)->capacity=Buffer_size; 
    int*new_array=(int*)malloc(sizeof(int)*Buffer_size); 
    for(int i=0;i<(*self)->size;i++) 
        new_array[i]=(*self)->arr[i]; 
    free((*self)->arr);
    (*self)->arr=new_array;
    return;
}

void stack_push(void**self,int data) 
{
    if(*self) 
    {
        if(((stack*)(*self))->size==((stack*)(*self))->capacity) 
            _realloc((stack**)self,((stack*)(*self))->capacity+((stack*)(*self))->capacity/2);
        if(((stack*)(*self))->empty) 
            ((stack*)(*self))->empty=0; 
        ((stack*)(*self))->arr[((stack*)(*self))->size]=data; 
        ((stack*)(*self))->size++;
    }
    return; 
}

void stack_pop(void**self) 
{
    if(*self) 
    {   
        ((stack*)(*self))->size--;
        if(((stack*)(*self))->size==0) 
            ((stack*)(*self))->empty=1; 
    }
    return; 
}

int stack_top(void*self) 
{
    if(self) 
        return ((stack*)self)->arr[((stack*)self)->size-1];
    exit(0); 
}

int stack_empty(void*self) 
{
    if(self) 
        return ((stack*)self)->empty;  
    exit(0); 
}

int stack_size(void*self) 
{
    if(self) 
        return ((stack*)self)->size; 
    exit(0); 
}

void stack_delete(void**self) 
{
    free((((stack*)(*self))->arr)); // The code works fine when this part is commented
    free(*self); 
    return;
}

main.c :-

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

int main(int argc,char**argv) 
{   
    void*stack=NULL; 
    stack_init(&stack); 
    stack_push(&stack,10);
    stack_push(&stack,20);
    stack_push(&stack,30);
    stack_push(&stack,40);
    printf("%d\n",stack_size(stack));
    while(!stack_empty(stack)) 
    {
        printf("%d ",stack_top(stack)); 
        stack_pop(&stack); 
    } 
    printf("\n");
    stack_delete(&stack); // error
    getc(stdin); 
    return 0; 
}

Update: I tested this code in Visual Studio IDE, and the code crashed with HEAP CORRUPTION DETECTED error, but I am not able to figure out how.


Solution

  • I think the problem is due to the fact that the value of the expression capacity + capacity/2, used by stack_push() when it calls _realloc(), is always equal to 1.

    Notice that, since capacity is int and has initial value 1, the value of the expression capacity/2 is 0.

    The initial stack capacity never increases, even after calling _realloc(), so function stack_push() accesses areas of memory that have not been properly allocated.