context:https://stackoverflow.com/a/50655730/15603477
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<ctype.h>
#include<limits.h>
#include<uchar.h>
#include<assert.h>
#define MAXW 128
#define MAXC 112
int main(int argc,char **argv)
{
int readdef = 0; /* flag for reading definition */
size_t offset = 0 /* offset for each part of definition */
,len = 0; /* length of each line */
char buf[MAXC] = ""; /* read (line) buffer */
char word[MAXW] = ""; /* buffer storing word */
char defn[MAXC] = ""; /* buffer storing definition */
/* open filename given as 1st argument, (or read stdin by default) */
FILE *fp = argc > 1 ? fopen(argv[1],"r") : stdin;
if(!fp){ /* validate file open for reading */
fprintf(stderr,"error: file '%s' open failed\n",argv[1]);
exit(EXIT_FAILURE);
}
while(fgets(buf,MAXC,fp))
{
char *p = buf; /* pointer to parse word & 1st part of defn */
if(*buf == '\n') {
defn[offset-1] = 0;
printf("defn:%s\n\n",defn);
readdef = 0;
offset= 0;
}
else if(readdef == 0)
{
while(*p && *p != '.') p++;
if(p-buf+1 > MAXW){
fprintf(stderr,"error: word exceeds %d chars.\n",MAXW-1);
exit(EXIT_FAILURE);
}
snprintf(word,p-buf+1,"%s",buf); /* copy to word */
printf("word=%s|\n",word);
while(ispunct(*p) || isspace(*p))
p++;
len = strlen(p);
if(len && p[len-1] == '\n')
p[len-1] = ' ';
strcpy(defn,p);
offset +=len;
readdef = 1;
}
else{
len = strlen(buf); /*get the line lenfth */
if(len && buf[len-1] == '\n') /* chk \n, overwite w/' ' */
buf[len-1] = ' ';
if(offset + len + 1 > MAXC){
fprintf(stderr,"error: definition exceed %d chars\n",MAXC-1);
// free(buf);
exit(EXIT_FAILURE);
}
snprintf(defn+offset,len+1,"%s",buf); /* append to defn */
offset += len; /*update offset*/
}
}
if(fp != stdin) fclose(fp);
defn[offset - 1] = 0;
printf("defn: %s\n\n",defn);
exit(EXIT_SUCCESS);
}
valgrind info.
error: definition exceed 111 chars
==28017==
==28017== HEAP SUMMARY:
==28017== in use at exit: 472 bytes in 1 blocks
==28017== total heap usage: 3 allocs, 2 frees, 5,592 bytes allocated
==28017==
==28017== 472 bytes in 1 blocks are still reachable in loss record 1 of 1
==28017== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==28017== by 0x48ED6CD: __fopen_internal (iofopen.c:65)
==28017== by 0x48ED6CD: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==28017== by 0x109285: main (in /home/jian/helloc/a.out)
==28017==
==28017== LEAK SUMMARY:
==28017== definitely lost: 0 bytes in 0 blocks
==28017== indirectly lost: 0 bytes in 0 blocks
==28017== possibly lost: 0 bytes in 0 blocks
==28017== still reachable: 472 bytes in 1 blocks
==28017== suppressed: 0 bytes in 0 blocks
==28017==
==28017== For lists of detected and suppressed errors, rerun with: -s
==28017== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
if MAXC is larger enough, then no LEAK SUMMARY. however if it's smaller, then there is memory leak error.
How can I fix the memory leak error when MAXC is not large enough to hold the string.
I also wonder even if dat/definitions.txt
first line is empty new line, then defn[offset-1] = 0;
would be defn[-1] = 0;
but gcc still no error. should i expect error or warning like above array bounds of array char[112]?