0

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
ks1322
  • 33,961
  • 14
  • 109
  • 164
  • StackOverflow is not a human-powered automated debugger. Do as Valgrind says: "Rerun with --leak-check=full to see details of leaked memory" - and update your question with more information on the issue and what you tried to solve it. – Marco Bonelli Nov 27 '21 at 14:57
  • 4
    ": not found: ./main.c: ./main.c: 6: ./main.c: Syntax error: "(" unexpected" You are not running what you think you are running. – n. m. could be an AI Nov 27 '21 at 15:10
  • 5
    On an unrelated note, *pay attention to your compiler warnings*. `getline` needs a `size_t*` not an `unsigned int*`. – n. m. could be an AI Nov 27 '21 at 15:11
  • You _must_ fix the `getline` related bug that n. mentioned. It is UB (undefined behavior) because [on a 64 bit machine], `unsigned int` is 32 bits but `size_t` is 64 bits. Because `reverse` does a `malloc` for its return value, `printf("%s\n", reverse(alllines[i]));` leaks that return value. Change to: `char *result = reverse(alllines[i]); printf("%s\n",result); free(result);` – Craig Estey Nov 27 '21 at 16:32

0 Answers0