We got this task at uni to use dynamic allocation, to solve this simple problem.
They also sent us 2 example codes. After implementing everything like they told us in class, I solved the problem (it works with all test cases), but when I run valgrind on it it finds still reachable bytes.
Here's my code:
#ifndef REVERSE
#define REVERSE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* reverse(char* s) {
int len = strlen(s);
char* result = malloc(sizeof(char) * (strlen(s) + 1));
if(!result) return NULL;
for(int i = 0; i < len; i++) {
result[i] = s[(len - 1) - i];
}
result[len] = '\0';
return result;
}
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "reverse.h"
int main(int argc, char** argv){
char** alllines;
int size=0;
if(argc < 2){
size=0;
FILE* fp = stdin;
unsigned int bufferSize = 1024;
char* line = malloc(sizeof(char)*bufferSize);
if (fp == NULL){
printf("File opening unsuccessful!");
exit(1);
}
while (getline(&line, &bufferSize, fp) != -1){
line[strcspn(line, "\n")] = '\0';
if(size == 0){
alllines = malloc(sizeof(char*) * 1);
if(!alllines) {
printf("Memory allocation failed!\n");
exit(1);
}
size++;
}
else{
alllines = realloc(alllines, sizeof(char*) * (++size));
if(!alllines){
printf("Memory allocation failed!\n");
exit(1);
}
}
alllines[size-1] = malloc(sizeof(char) * (strlen(line) + 1));
strcpy(alllines[size-1], line);
}
for(int i = size - 1; i >= 0; i--) {
printf("%d ", i+1);
printf("%s\n", reverse(alllines[i]));
}
fclose(fp);
if (line)
free(line);
for(int i = 0; i < size; i++)
free(alllines[i]);
if(size > 0)
free(alllines);
}else{
for(int i = 1; i < argc; i++){
size = 0;
FILE* fp;
unsigned int bufferSize = 1024;
char* line = malloc(sizeof(char)*bufferSize);
char* filename = argv[i];
fp = fopen(filename, "r");
if (fp == NULL){
printf("File opening unsuccessful!");
exit(1);
}
while (getline(&line, &bufferSize, fp) != -1){
line[strcspn(line, "\n")] = '\0';
if(size == 0){
alllines = malloc(sizeof(char*) * 1);
if(!alllines) {
printf("Memory allocation failed!\n");
exit(1);
}
size++;
}
else{
alllines = realloc(alllines, sizeof(char*) * (++size));
if(!alllines){
printf("Memory allocation failed!\n");
exit(1);
}
}
alllines[size-1] = malloc(sizeof(char) * (strlen(line) + 1));
strcpy(alllines[size-1], line);
}
for(int i = size - 1; i >= 0; i--){
printf("%d ", i+1);
printf("%s\n", reverse(alllines[i]));
}
fclose(fp);
if (line)
free(line);
for(int i = 0; i < size; i++)
free(alllines[i]);
if(size > 0)
free(alllines);
}
}
return(0);
}
Here's the valgrind message:
==399== Memcheck, a memory error detector
==399== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==399== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==399== Command: ./main.c
==399==
==399== error calling PR_SET_PTRACER, vgdb might block
: not found: ./main.c:
./main.c: 6: ./main.c: Syntax error: "(" unexpected
==399==
==399== HEAP SUMMARY:
==399== in use at exit: 821 bytes in 26 blocks
==399== total heap usage: 31 allocs, 5 frees, 2,885 bytes allocated
==399==
==399== LEAK SUMMARY:
==399== definitely lost: 0 bytes in 0 blocks
==399== indirectly lost: 0 bytes in 0 blocks
==399== possibly lost: 0 bytes in 0 blocks
==399== still reachable: 821 bytes in 26 blocks
==399== suppressed: 0 bytes in 0 blocks
==399== Rerun with --leak-check=full to see details of leaked memory
==399==
==399== For counts of detected and suppressed errors, rerun with: -v
==399== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
test.txt
12345
asddfhdfh
abcdefgh
76543