I’ve been trying to tackle Project logfind by myself and I thought to add the line numbers and indexes as an extra feature. I used two files: log_input.c
checked for matches in the files and printed them, and logfind.c
processed the arguments and did the globbing.
The code ended up pretty gnarly-looking in log_input.c
but when it was completed, I ran into a new error, corrupted size vs. prev_size which was unexpected. Reading up online, I found it could happen if you wrote more bytes than malloc or realloc gave you. But when I ran a backtrace using lldb
, it seemed to originate from log_input.c:135
which was just a normal fclose()
. Since I couldn’t find anything on fclose()
outputting errors like that, I decided to turn here.
log_input.c:
#include <stdio.h>
#include <stdlib.h>
#include "dbg.h"
struct Linedet {
int lnum;
int *s;
int *l;
char *line;
char **matches;
};
struct Matchdata {
int s;
int l;
char *match;
};
char *match[] = {"random"};
int match_ln = 1;
void die (char *message)
{
if (errno) {
perror (message);
} else {
printf ("%s\n", message);
}
exit (1);
}
struct Matchdata *check_input (char *string, int *found)
{
int i = 0;
int matches = 0;
int strln = strlen (string);
struct Matchdata *mts = NULL;
for (i = 0; i < strln; i++) {
int k = 0;
while (k < match_ln) {
if (string[i] == match[k][0]) {
debug ("Letter matched...");
int j = 0;
int mln = strlen (match[k]);
for (j = 1; j < mln; j++) {
if (string[i+j] == match[k][j] && j == (mln - 1)) {
debug ("String matched...");
struct Matchdata mat = { .s = i, .l = i+j, .match = match[k] };
mts = realloc (mts, sizeof (struct Matchdata) * (matches + 1));
mts[matches] = mat;
matches++;
} else if (string[i+j] == match[k][j]) {
debug ("Another letter matched...");
continue;
} else {
break;
}
}
}
k++;
}
}
*found = matches;
return mts;
}
struct Linedet *readline (const char *filename, int *ar_size, int *match_no)
{
struct Linedet *array = NULL;
int i = 0;
int n = 1;
int found;
int matches;
int j = 0;
char *rc;
char *str = malloc (256);
debug ("Opening file...");
FILE *file = fopen (filename, "rb");
if (file == NULL)
die ("File open failed");
debug ("Starting while loop...");
while (n) {
debug ("Reading from file...");
rc = fgets (str, 256, file);
if (rc == NULL)
break;
debug ("Calling check_input...");
struct Matchdata *irc = check_input (str, &matches);
if (irc != NULL) {
size_t mt_size;
found = 1;
debug ("Allocating memory for array...");
array = realloc (array, sizeof (struct Linedet) * (i+1));
if (array == NULL)
die ("Memory error");
debug ("Creating structure...");
struct Linedet lndt = {.lnum = n, .line = strdup (str)};
for (j = 0; j < found; j++) {
mt_size += strlen (irc[j].match) + 1;
lndt.s = realloc (lndt.s, sizeof (int) * (j+1));
lndt.l = realloc (lndt.l, sizeof (int) * (j+1));
lndt.matches = realloc (lndt.matches, mt_size);
lndt.s[j] = irc[j].s;
lndt.l[j] = irc[j].l;
lndt.matches[j] = irc[j].match;
}
debug ("Assigning structure to array...");
array[i] = lndt;
i++;
}
n++;
free (irc);
}
*ar_size = i;
*match_no = matches;
debug ("Exited while loop...");
debug ("Closing file and freeing memory...");
fclose (file);
free (str);
if (found) {
return array;
} else {
goto error;
}
error:
return NULL;
}
void memfree (int ar_size, int match_no, struct Linedet *array)
{
int i = 0;
for (i = 0; i < ar_size; i++) {
free (array[i].line);
free (array[i].s);
free (array[i].l);
free (array[i].matches);
}
free (array);
}
int main (int argc, char *argv[])
{
if (argc != 2)
die ("USAGE: log_input <file>");
int ar_size;
int match_no;
struct Linedet *array = readline (argv[1], &ar_size, &match_no);
int i = 0;
int j = 0;
for (i = 0; i < ar_size; i++) {
printf ("In line %d: \n", array[i].lnum);
for (j = 0; j < match_no; j++) {
printf ("Found '%s' at index %d:\n", array[i].matches[j], array[i].s[j]);
printf ("Text: %s", array[i].line);
}
}
debug ("Freeing array...");
memfree (ar_size, match_no, array);
return 0;
}
I’ve been working on this a few days and I was almost about to scrap it and start new because I didn’t like how it looked, but this error caught my notice and I thought I’d ask what it meant here. At the time I was unaware of strstr()
so I created my own function to check for matches. I hope someone can help. Thanks in advance!
PS: I’d be grateful if you could tell me where I could improve my code.
Edit: A few more tests revealed that most random text I put in the file gave the error realloc(): invalid next size
. I still would like to know if fclose()
could indeed output that error, and why. The new error seems to come from log_input.c:52
, the reason for which I still haven’t figured out.