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.
User contributions licensed under CC BY-SA 3.0