I have the following code, and am specifically having problems with the print_file_results function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
int bytes_flag,lines_flag, words_flag;
int arg_in;
static struct option long_opts [] = {
{"bytes", no_argument, 0, 'c'},
{"lines", no_argument, 0, 'l'},
{0,0,0,0}
};
int count_bytes(const char *filename){
FILE * file_stream;
int byte_count = 0;
file_stream = fopen(filename, "r");
if (file_stream == NULL){
printf("File could not be opened.\n");
}
else{
while (getc(file_stream) != EOF){
byte_count ++;
}
fclose(file_stream);
}
return byte_count;
}
void print_file_results(const int bytes, const int lines, const int words, const char *filename, const int size){
char * results = malloc(size * 2 + 1);
printf(results);
printf("\n");
char int_buffer[4];
if (bytes != 0) {
sprintf(int_buffer, "%d ", bytes);
strcpy(results, int_buffer);
printf(results);
printf("\n");
}
if (lines != 0) {
//TODO
}
if (words != 0) {
//TODO
}
printf("%s%s\n", results, filename);
free(results);
return;
}
int main (int argc, char * argv[]) {
while(1){
arg_in = getopt_long (argc, argv, "cl", long_opts, NULL);
if (arg_in == -1){
break;
}
switch(arg_in){
case 'c':
printf("Byte count\n");
bytes_flag = 1;
break;
case 'l':
printf("Line count\n");
lines_flag = 1;
break;
default:
abort();
}
}
if (optind < argc){
while (optind < argc){
int bytes_total = 0;
int lines_total = 0;
int words_total = 0;
printf("Current file %s\n", argv[optind]);
if ( bytes_flag ){
bytes_total = count_bytes(argv[optind]);
}
if (lines_flag){
continue;
}
if (words_flag){
continue;
}
print_file_results(bytes_total, lines_total, words_total, argv[optind] , bytes_flag+lines_flag+words_flag);
optind++;
}
}
else {
printf("No files given\n");
exit(1);
}
exit(0);
}
The following output is received
❯ ./ccwc.o -c test.txt
Byte count
Current file test.txt
ation is committed to coa
342190
342190 test.txt
*** stack smashing detected ***: terminated
[1] 125314 IOT instruction (core dumped) ./ccwc.o -c test.txt
My question is why does the random string appear in the results object that was malloced, and why does it appear to be more bytes than I allocated? I am also unsure why I am getting a stack smash, but first would like to understand my error in the object I am creating with malloc. Besides my confusion with the arrays initial values and the stack smash, the program seems to actually be printing the expected results with my test case, though obviously it crashing isn’t ideal!
>Solution :
Memory returned from malloc is uninitialized. So when you attempt to read the string, you’re reading whatever garbage was left there. And if there’s no null byte set within the allocated memory, anything that expects it to be a string will read past the end of allocated memory, triggering undefined behavior which in your cases causes your code to crash.
So don’t read uninitialized memory.