Command line argument causing heap corruption

1

I'm trying to write a buffer using C, it was supposed to take in contents from an input file and output it to another text file. However, when I try to debug it in Visual Studio 2019, it always trigger a breakpoint at if ((fi = fopen(argv[1],"r")) == NULL){...} of my test file, it also detected a critical error of C0000374. My command line argument is buffer.exe ass1.pls a

My test file : platy_bt.c


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

#include "buffer.h"


/*check for ANSI C compliancy */
#define ANSI_C 0
#if defined(__STDC__)
#undef ANSI_C
#define ANSI_C 1
#endif

/*  Declaration of an error printing function with
 *  variable number of arguments
 */
void err_printf(char *fmt, ...);
/*  Declaration of a buffer contents display function */
void display (Buffer *ptr_Buffer); 
long get_filesize(char *fname);

int main(int argc, char **argv){

   pBuffer ptr_Buffer;   /* pointer to Buffer structure */
   FILE *fi;             /* input file handle */
   int loadsize = 0;     /* the size of the file loaded in the buffer */
   int ansi_c = !ANSI_C; /* ANSI C compliancy flag */
   char symbol;          /* symbol read from input file */ 
/* Check if the compiler option is set to compile ANSI C */
/* __DATE__, __TIME__, __LINE__, __FILE__, __STDC__ are predefined preprocessor macros*/
  if(ansi_c){
    err_printf("Date: %s  Time: %s",__DATE__, __TIME__);
    err_printf("ERROR: Compiler is not ANSI C compliant!\n");
    exit(1);
  }

/* missing file name or/and mode parameter */
  if (argc <= 2){

     err_printf("\nDate: %s  Time: %s",__DATE__, __TIME__);
     err_printf("\nRuntime error at line %d in file %s\n", __LINE__, __FILE__);
      err_printf("%s\b\b\b\b%s%s",argv[0],": ","Missing parameters.");
      err_printf("Usage: platybt source_file_name mode");
      exit(1);
    }

/* create a source code input buffer */     
    switch(*argv[2]){
     case 'f': case 'a': case 'm': break;
     default:
      err_printf("%s%s%s",argv[0],": ","Wrong mode parameter.");
      exit(1);
    }
/*create the input buffer */
    ptr_Buffer = b_allocate(0,0,*argv[2]);




    if (ptr_Buffer == NULL){
        err_printf("%s%s%s",argv[0],": ","Cannot allocate buffer.");
        exit(1);
    }

/* open the source file */
    if ((fi = fopen(argv[1],"r")) == NULL){
        err_printf("%s%s%s%s",argv[0],": ", "Cannot open file: ",argv[1]);
        exit (1);
    }

/* load a source file into the input buffer  */
     printf("Reading file %s ....Please wait\n",argv[1]);
     loadsize = b_load (fi,ptr_Buffer);
     if(loadsize == RT_FAIL_1)
       err_printf("%s%s%s",argv[0],": ","Error in loading buffer.");

/*if the input file has not been completely loaded, find the file size and print the last symbol loaded */
    if (loadsize == LOAD_FAIL){
      printf("The input file %s %s\n", argv[1],"has not been completely loaded.");
      symbol = (char)fgetc(fi);
      printf("Last character read from the input file is: %c %d\n", symbol, symbol);
      printf("Input file size: %ld\n", get_filesize(argv[1]));
    } 

/* close source file */
   fclose(fi);

/* display the contents of the input buffer */    
   display(ptr_Buffer);

/* compact the buffer
 * add end-of-file character (EOF) to the buffer
 * display again
 */
if(!b_compact(ptr_Buffer,EOF)){         
      err_printf("%s%s%s",argv[0],": ","Error in compacting buffer.");
  }  
  display(ptr_Buffer); 

/* free the dynamic memory used by the buffer */  
  b_free(ptr_Buffer);
/* make the buffer invalid
   It is not necessary here because the function terminates anyway,
   but will prevent run-time errors and crashes in future expansions
*/
  ptr_Buffer = NULL;
/*return success */
  return (0);
}

/* error printing function with variable number of arguments*/
void err_printf( char *fmt, ... ){
/*Initialize variable list */   
  va_list ap;
  va_start(ap, fmt);

  (void)vfprintf(stderr, fmt, ap);
   va_end(ap);

  /* Move to new line */
  if( strchr(fmt,'\n') == NULL )
     fprintf(stderr,"\n");
}

void display (Buffer *ptr_Buffer){
  printf("\nPrinting buffer parameters:\n\n");
  printf("The capacity of the buffer is:  %d\n",b_capacity(ptr_Buffer));
  printf("The current size of the buffer is:  %d\n", b_addcoffset(ptr_Buffer));
  printf("The operational mode of the buffer is:   %d\n",b_mode(ptr_Buffer));
  printf("The increment factor of the buffer is:  %lu\n",b_incfactor(ptr_Buffer));
  printf("The first symbol in the buffer is:  %c\n", b_addcoffset(ptr_Buffer)?*b_location(ptr_Buffer, 0):' ');
  printf("The value of the flags field is: %04hX\n",ptr_Buffer->flags);
  printf("\nPrinting buffer contents:\n\n");
  b_rewind(ptr_Buffer);
  if (!b_print(ptr_Buffer,1)) printf("empty buffer\n");
}

long get_filesize(char  *fname){
   FILE *input;
   long flength;
   input = fopen(fname, "r");
   if(input == NULL){
      err_printf("%s%s","Cannot open file: ",fname);  
      return 0;
   }
   fseek(input, 0L, SEEK_END);
   flength = ftell(input);   
   fclose(input);
   return flength;
}
<!-- -->

My buffer.c

#include "buffer.h";
#include <string.h>;
#include <stdlib.h>;
Buffer* b_allocate(short init_capacity, char inc_factor, char o_mode) {

    char* characterArray;

    if(init_capacity <0 ||  init_capacity >= SHRT_MAX) {
        printf("Capacity exceed the limit, must be between 0 and %d.", SHRT_MAX);

        return NULL;

    }



    else {

        pBuffer bufferStructure = (pBuffer) calloc(init_capacity, sizeof(Buffer));
        if (init_capacity == 0) {
            init_capacity = DEFAULT_INIT_CAPACITY;

            if (o_mode=='a' || o_mode== 'm') {

                inc_factor = DEFAULT_INC_FACTOR;
                bufferStructure->inc_factor = inc_factor;
            }
            else {
                if (o_mode== 'f') {
                    inc_factor = 0;
                    bufferStructure->inc_factor = inc_factor;
                }
            }

            characterArray = (char *) malloc(DEFAULT_INIT_CAPACITY);


        }
        else {

            characterArray = (char*) malloc(init_capacity);
        }



        bufferStructure->cb_head = characterArray;
        if (inc_factor == 0 && init_capacity != 0) {
            bufferStructure->mode = 0;
            bufferStructure->inc_factor = 0;


        }

        switch (o_mode) {
        case 'f':
            bufferStructure->mode = 0;
            bufferStructure->inc_factor = 0;
            break;
        case 'a':




            if (inc_factor >= 1 && inc_factor <= 255) {
                bufferStructure->mode = 1;
                bufferStructure->inc_factor = inc_factor;
                break;


            }
            else {
                if (inc_factor != 0) {
                    return NULL;
                    break;
                }
            }
        case 'm':
            if (inc_factor >= 1 && inc_factor <= 100) {
                bufferStructure->mode = -1;
                bufferStructure->inc_factor = inc_factor;
                break;


            }
            else {
                if (inc_factor != 0) {
                    return NULL;
                    break;
                }
            }

            }
        bufferStructure->capacity =  200;

        bufferStructure->flags = DEFAULT_FLAGS;
        bufferStructure->addc_offset = 0;
        bufferStructure->getc_offset = 0;
        bufferStructure->markc_offset;

        return bufferStructure;




        }




    }

    pBuffer b_addc(pBuffer const pBD, char symbol) {
        int inc_factor = pBD->inc_factor - '0';
        int newCapacity = 0;
        int availableSpace =0;
        long newIncrement = 0;


        pBD->flags &= RESET_R_FLAG;
        char* ptr;

        if (pBD->addc_offset <= pBD->capacity) {
            pBD->cb_head[pBD->addc_offset] = symbol;
            pBD->addc_offset++;

            return pBD;
        }
        else {
            switch (pBD->mode) {
            case 0:
                return NULL;
                break;
            case 1:

                newCapacity = pBD->capacity + inc_factor;

                if (newCapacity > 0 && newCapacity < (SHRT_MAX - 1)) {
                    if (realloc(pBD->cb_head, newCapacity)) {
                        pBD->flags |= SET_R_FLAG;
                        pBD->cb_head[pBD->addc_offset] = symbol;
                        pBD->addc_offset++;
                        pBD->capacity = (short)newCapacity;
                        ptr =  realloc(pBD->cb_head, newCapacity);
                        pBD->cb_head = ptr;
                        return pBD;
                    }
                    else {

                        return NULL;
                    }


                }
                else {
                    if (newCapacity > 0 && newCapacity >= (SHRT_MAX - 1)) {
                        newCapacity = SHRT_MAX - 1;
                        if (realloc(pBD->cb_head, newCapacity)) {
                            pBD->flags |= SET_R_FLAG;
                            pBD->cb_head[pBD->addc_offset] = symbol;
                            pBD->addc_offset++;
                            pBD->capacity = (short) newCapacity;
                            ptr = realloc(pBD->cb_head, newCapacity);
                            pBD->cb_head = ptr;
                            return pBD;
                        }
                        else {

                            return NULL;
                        }


                    }
                    else {
                        if (newCapacity <= 0) {
                            return NULL;

                        }



                    }

                }
                break;
            case -1:
                if (pBD->capacity >= SHRT_MAX -1) {

                    return NULL;


                }
                else {
                    availableSpace = SHRT_MAX - 1 - pBD->capacity;
                    newIncrement = (long)(availableSpace * inc_factor/100);
                    newCapacity = (short)(pBD->capacity + newIncrement);
                    if (newCapacity >= SHRT_MAX-1) {
                        newCapacity = SHRT_MAX - 1;

                    }
                    else {

                        if (newCapacity > 0 && newCapacity < SHRT_MAX - 1) {
                            if (realloc(pBD->cb_head, newCapacity)) {
                                pBD->flags |= SET_R_FLAG;
                                pBD->cb_head[pBD->addc_offset] = symbol;
                                pBD->addc_offset++;
                                pBD->capacity = (short)newCapacity;
                                ptr = realloc(pBD->cb_head, newCapacity);
                                pBD->cb_head = ptr;
                                return pBD;
                            }
                            else {

                                return NULL;
                            }
                        }

                    }
                }



                break;

            }


        }
}

int b_clear(Buffer* const pBD) {
    pBD->addc_offset = 0;
    pBD->getc_offset = 0;
    pBD->markc_offset = 0;
    pBD->flags = DEFAULT_FLAGS;

    return 1;

}
void b_free(Buffer* const pBD) {

    free(pBD->cb_head);
    free(pBD);


}
short b_capacity(Buffer* const pBD) {
    if (pBD->capacity != 0) {
        return pBD->capacity;
    }
    else {
        return -1;
    }

}

short b_addcoffset(Buffer* const pBD) {
    if (pBD->addc_offset != 0 ) {
        return pBD->addc_offset;
    }
    else {
        return -1;
    }

}

short b_markc(pBuffer const pBD, short mark) {
    if (mark<0 || mark > pBD->addc_offset) {

        return -1;
    }
    else {

        pBD->markc_offset = mark;
        return pBD->markc_offset;
    }

}

short b_getcoffset(Buffer* const pBD) {
    if (pBD->getc_offset >=0) {
        return pBD->getc_offset;
    }
    else {
        return -1;
    }


}
int b_mode(Buffer* const pBD) {

    if (pBD->mode) {
        return pBD->mode;
    }
    else {
        printf("Not found");
    }



}

size_t b_incfactor(Buffer* const pBD) {
    unsigned char inc_factor = pBD->inc_factor;
    size_t inc_factor_value = inc_factor;
    if (pBD->inc_factor) {


        return inc_factor_value;
    }
    else {
        return 0x100;
    }



}

char b_getc(Buffer* const pBD) {
    if (pBD->getc_offset > pBD->addc_offset) {
        return -2;

    }
    else {
        if (pBD->getc_offset == pBD->addc_offset) {
            pBD->flags &= RESET_EOB;
            pBD->flags |= SET_EOB;
            pBD->getc_offset++;
            return 0;
        }
        else {
            pBD->flags &= RESET_EOB;
            pBD->getc_offset++;
            return pBD->cb_head[pBD->getc_offset];


        }

    }



}
int b_print(Buffer* const pBD, char nl) {

    while (b_eob(pBD)==0) {

            printf("%c", b_getc(pBD));



    }
    if (nl != 0) {
        printf("\n");
    }

    return nl;







}



int b_eob(Buffer* const pBD) {
    if ((pBD->flags & CHECK_EOB) > 0) {
        return pBD->flags & CHECK_EOB;


    }
    else {
        if ((pBD->flags & CHECK_EOB) == 0) {

            return 0;
        }
        else {
            return -1;
        }

    }

}


char b_rflag(Buffer* const pBD) {
    if ((pBD->flags & CHECK_R_FLAG) > 0) {
        return pBD->flags & CHECK_R_FLAG ;


    }
    else {
        if ((pBD->flags & CHECK_R_FLAG) == 0) {

            return 0;
        }
        else {
            return -1;
        }

    }

}

int b_isfull(Buffer* const pBD) {
    if (pBD->addc_offset == pBD->capacity) {
        return 0;
    }
    else {
        if (pBD->addc_offset < pBD->capacity) {
            return 1;

        }
        else {
            return -1;

        }
    }


}


int b_isempty(Buffer* const pBD) {
    if (pBD->addc_offset == 0) {
        return 1;
    }
    else {
        if (pBD->addc_offset > 0) {
            return 0;

        }
        else {
            return -1;
        }
    }

}



char* b_location(Buffer* const pBD, short loc_offset) {
    if ( loc_offset > pBD->addc_offset) {
        return NULL;
    }
    else {
        return &pBD->cb_head[loc_offset];

    }




}


int b_load(FILE* const fi, Buffer* const pBD) {
    while (!feof(fi)) {

        char symbol = (char)fgetc(fi);
        if (b_addc(pBD, symbol) != NULL) {



        }
        else {

            ungetc(symbol, fi);
            return LOAD_FAIL;

        }



    }
    return pBD->addc_offset;



}

Buffer* b_compact(Buffer* const pBD, char symbol) {
    short newCapacity = pBD->addc_offset+1;
    char * ptr = (char *)realloc(pBD, newCapacity);
    pBD->cb_head = ptr;
    pBD->capacity = (short)newCapacity;
    pBD->cb_head[pBD->addc_offset] = symbol;
    pBD->addc_offset++;
    pBD->flags &= RESET_R_FLAG;
    pBD->flags |= SET_R_FLAG;

    return pBD;


}

short b_retract(Buffer* const pBD) {
    if (pBD->getc_offset <= 0) {
        return -1;
    }
    else {

        pBD->getc_offset--;
        return pBD->getc_offset;
    }


}
short b_reset(Buffer* const pBD) {
    if (pBD->getc_offset > pBD->addc_offset || pBD->markc_offset < 0) {
        return -1;
    }
    else {
        pBD->getc_offset = pBD->markc_offset;
    }

    return pBD->getc_offset;

}

int b_rewind(Buffer* const pBD) {

    pBD->getc_offset = 0;
        pBD->markc_offset = 0;
        return 0;
}
<!-- -->

My buffer.h

#ifndef BUFFER_H_
#define BUFFER_H_

/*#pragma warning(1:4001) *//*to enforce C89 type comments  - to make //comments an warning */

/*#pragma warning(error:4001)*//* to enforce C89 comments - to make // comments an error */

/* standard header files */
#include <stdio.h>  /* standard input/output */
#include <malloc.h> /* for dynamic memory allocation*/
#include <limits.h> /* implementation-defined data type ranges and limits */

/* constant definitions */
#define RT_FAIL_1 (-1)         /* operation failure return value 1 */
#define RT_FAIL_2 (-2)         /* operation failure return value 2 */
#define LOAD_FAIL (-2)         /* load fail return value */

#define DEFAULT_INIT_CAPACITY 200   /* default initial buffer capacity */
#define DEFAULT_INC_FACTOR 15       /* default increment factor */


/* You should add your own constant definitions here */

/* Add your bit-masks constant definitions here */
#define DEFAULT_FLAGS  0xFFF9 
#define SET_EOB  0x0002 
#define RESET_EOB 0xFFFD
#define CHECK_EOB 0x0002
#define SET_R_FLAG  0x0004
#define RESET_R_FLAG 0xFFFB
#define CHECK_R_FLAG 0x0004
#define DEFAULTZ    0x0000   /* 0000 0000 0000 0000 */


#define SET_LSB     0x0001   /* 0000 0000 0000 0001 */
#define RESET_LSB   0xFFFE   /* 1111 1111 1111 1110 */
#define CHK_LSB     0x0001   /* 0000 0000 0000 0001 */

/* user data type declarations */
typedef struct BufferDescriptor {
    char *cb_head;   /* pointer to the beginning of character array (character buffer) */
    short capacity;    /* current dynamic memory size (in bytes) allocated to character buffer */
    char  inc_factor; /* character array increment factor */
    char  mode;       /* operational mode indicator*/
    unsigned short flags;     /* contains character array reallocation flag and end-of-buffer flag */
    short addc_offset;  /* the offset (in chars) to the add-character location */
    short getc_offset;  /* the offset (in chars) to the get-character location */
    short markc_offset; /* the offset (in chars) to the mark location */
} Buffer, *pBuffer;
/*typedef Buffer *pBuffer;*/

/* function declarations */
/*
Place your function declarations here.
Do not include the function header comments here.
Place them in the buffer.c file
*/
Buffer* b_allocate(short init_capacity, char inc_factor, char o_mode);
pBuffer b_addc(pBuffer const pBD, char symbol);
int b_clear(Buffer* const pBD);
void b_free(Buffer* const pBD);
int b_isfull(Buffer* const pBD);
short b_addcoffset(Buffer* const pBD);
short b_capacity(Buffer* const pBD);
short b_markc(pBuffer const pBD, short mark);
int b_mode(Buffer* const pBD);
size_t b_incfactor(Buffer* const pBD);
int b_load(FILE* const fi, Buffer* const pBD);
int b_isempty(Buffer* const pBD);
char b_getc(Buffer* const pBD);
int b_eob(Buffer* const pBD);
int b_print(Buffer* const pBD, char nl);
Buffer* b_compact(Buffer* const pBD, char symbol);
char b_rflag(Buffer* const pBD);
short b_retract(Buffer* const pBD);
short b_reset(Buffer* const pBD);
short b_getcoffset(Buffer* const pBD);
int b_rewind(Buffer* const pBD);
char* b_location(Buffer* const pBD, short loc_offset);



If I try to countinue with debugging, it output : Unhandled exception at 0x774DFA1D (ntdll.dll) in buffer.exe: 0xC0000374: A heap has been corrupted (parameters: 0x7751B960). and Unhandled exception at 0x7743C5D7 (ntdll.dll) in buffer.exe: 0xC0000005: Access violation reading location 0x00985A7A.. If I build this and run it in release mode, it cause assertion violation.

c
heap-corruption
asked on Stack Overflow Jun 7, 2020 by randomtrekker • edited Jun 7, 2020 by randomtrekker

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0