I'm trying to print certain lines from files to the console. I'm using a dynamically allocated array to keep track of lines i want to print and if more memory needed i realloc it.
void print_with_context(int* arr, char* file, int arr_size){
if(arr_size == 0)
return;
FILE* stream;
char* line = NULL;
size_t len = 0;
int line_number = 1;
stream = fopen(file, "r");
if(!stream)
die("fopen");
smallest_to_biggest_sort(arr, arr_size);
int i = 0;
while(arr[i] <= 0 && i < arr_size) //ignore negative lines
i;
while(getline(&line, &len, stream) != -1){
if(i >= arr_size)
break;
if(i > 0){
if(arr[i] == arr[i - 1]){
i;
continue;
}
}
if(arr[i] == line_number){
print_cwd(); //print current working directory
int success = printf("%s:%d:", file, line_number);
if(success < 0)
die("printf with context");
errno = 0;
int line_length = strlen(line);
int fwrite_success = fwrite(line, line_length, 1, stdout);
if(fwrite_success){
if(errno != 0)
die("fwrite");
}
i;
}
line_number;
}
free(line);
if(fclose(stream))
die("fclose");
}
void print_regex(struct stat* file_info, regex_t* regex_line, char* file){
if(!S_ISREG(file_info->st_mode))
return;
if(!regex_line)
return;
size_t nmatch = 1;
regmatch_t pmatch[1];
FILE* stream;
char* line = NULL;
size_t len = 0;
int line_number = 1;
stream = fopen(file, "r");
if(!stream)
die("fopen");
int* arr = malloc(array_length * sizeof(int));
if(!arr)
die("malloc");
int start = 1, line_found = 0, i = 0;
while(getline(&line, &len, stream) != -1){
if(regexec(regex_line, line, nmatch, pmatch, 0) != REG_NOMATCH){
line_found;
if(line_found > resize){
resize;
array_length = 2 * context 1;
errno = 0;
arr = realloc(arr, array_length);// <= here fails with the error
if(errno == ENOMEM)
die("realloc in print_regex");
}
start = line_number - context;
for(;i < array_length; i)
arr[i] = start ;
}
line_number;
}
print_with_context(arr, file, i);
free(arr);
free(line);
if(fclose(stream))
die("fclose");
}
I tried debugging it with valgrind but with no success. Here's the output from valgrind:
==11041== Memcheck, a memory error detector
==11041== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==11041== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==11041== Command: ./crawl . -line=print* -context=3
==11041==
==11041== Invalid write of size 4
==11041== at 0x109E25: print_regex (crawl.c:392)
==11041== by 0x10A4A2: crawl (crawl.c:518)
==11041== by 0x10A503: crawl (crawl.c:524)
==11041== by 0x10A503: crawl (crawl.c:524)
==11041== by 0x10A82B: main (crawl.c:579)
==11041== Address 0x4a8824c is 14 bytes after a block of size 14 alloc'd
==11041== at 0x4846CC3: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11041== by 0x109DD6: print_regex (crawl.c:385)
==11041== by 0x10A4A2: crawl (crawl.c:518)
==11041== by 0x10A503: crawl (crawl.c:524)
==11041== by 0x10A503: crawl (crawl.c:524)
==11041== by 0x10A82B: main (crawl.c:579)
==11041==
--11041-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--11041-- si_code=1; Faulting address: 0x3E04A88294; sp: 0x1002ca9e40
valgrind: the 'impossible' happened:
Killed by fatal signal
host stacktrace:
==11041== at 0x5804D09B: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==11041== by 0x580056B2: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==11041== by 0x5809B33D: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==11041== by 0x580E40C0: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable (lwpid 11041)
==11041== at 0x4846CC3: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11041== by 0x109DD6: print_regex (crawl.c:385)
==11041== by 0x10A4A2: crawl (crawl.c:518)
==11041== by 0x10A503: crawl (crawl.c:524)
==11041== by 0x10A503: crawl (crawl.c:524)
==11041== by 0x10A82B: main (crawl.c:579)
client stack range: [0x1FFEFFA000 0x1FFF000FFF] client SP: 0x1FFEFFFC30
valgrind stack range: [0x1002BAA000 0x1002CA9FFF] top usage: 10752 of 1048576
It doesn't crash the first time reallocing. It always does crush when it tries to realloc for the 2nd time. When it reallocs just one time it doesn't crush in the function but it does crash in main()
before finishing the program. One time I also managed to get the malloc(): unsorted double linked list corrupted error. So what exactly am I doing wrong here?
CodePudding user response:
My guess is that you are writing to the array out of bounds in the line
arr[i] = start ;
because the line
arr = realloc(arr, array_length);
is allocating insufficient memory.
Note that in the line
int* arr = malloc(array_length * sizeof(int));
you are allocating array_length * sizeof(int)
bytes, whereas in the line
arr = realloc(arr, array_length);
you are only allocating array_length
bytes, i.e. the * sizeof(int)
part is missing.