C program can't figure out how to properly free mallocs - c

In the main function of my program I make a few malloc calls and what I think are the right free calls at the end. My address sanitizer is telling me that data is still leaking in line 206, which is:
names[size - 1] = malloc(17 * sizeof(char));
The problem is that if I include a free statement for names[size - 1], there is apparently data still leaking from it. I have no idea why. Here is the main:
int main(int argc, char** argv) {
if (argc - 1 != 1) {
printf("Invalid number of arguments\n");
return 0;
}
//get file, return if invalid path
FILE *file = fopen(argv[1], "r");
if (!file) {
printf("Invalid input\n");
return 0;
}
//make temp of circuit with struct directive
int scount = 0;
struct directive* temp = NULL;
int size = 2;
int icount = 0;
int ocount = 0;
int tcount = 0;
char dir[17];
char **names;
int *values;
//get INPUT info
fscanf(file, " %s", dir);
fscanf(file, "%d", &icount);
size += icount;
names = malloc(size * sizeof(char *));
names[0] = malloc(2 * sizeof(char)); //MALLOC
strcpy(names[0], "0");
names[1] = malloc(2 * sizeof(char)); //MALLOC
strcpy(names[1], "1");
int i;
for (i = 0; i < icount; i++) {
names[i + 2] = malloc(17 * sizeof(char));
fscanf(file, "%*[: ]%16s", names[i + 2]);
}
//get OUTPUT info
fscanf(file, " %s", dir);
fscanf(file, "%d", &ocount);
size += ocount;
names = realloc(names, size * sizeof(char *));
for (i = 0; i < ocount; i++) {
names[i + icount + 2] = malloc(17 * sizeof(char));
fscanf(file, "%*[: ]%16s", names[i + icount + 2]);
}
//get temp
struct directive step;
while (!feof(file)) {
int numInputs = 2, numOutputs = 1;
int sc = fscanf(file, " %s", dir);
if (sc != 1) {
break;
}
scount++;
step.n = 0;
step.s = 0;
strcpy(step.gate, dir);
if (strcmp(dir, "NOT") == 0) {
numInputs = 1;
}
if (strcmp(dir, "PASS") == 0) {
numInputs = 1;
}
if (strcmp(dir, "DECODER") == 0) {
fscanf(file, "%d", &numInputs);
step.n = numInputs;
numOutputs = pow(2, numInputs);
}
if (strcmp(dir, "MULTIPLEXER") == 0) {
fscanf(file, "%d", &numInputs);
step.s = numInputs;
numInputs = pow(2, numInputs);
}
step.inputs = malloc(numInputs * sizeof(int));
step.outputs = malloc(numOutputs * sizeof(int));
step.selectors = malloc(step.s * sizeof(int));
char v[17];
for (i = 0; i < numInputs; i++) {
fscanf(file, "%*[: ]%16s", v);
step.inputs[i] = indexOf(size, names, v);
}
for (i = 0; i < step.s; i++) {
fscanf(file, "%*[: ]%16s", v);
step.selectors[i] = indexOf(size, names, v);
}
for (i = 0; i < numOutputs; i++) {
fscanf(file, "%*[: ]%16s", v);
int idx = indexOf(size, names, v);
if (idx == -1) {
size++;
tcount++;
char **tmp = realloc(names, size * sizeof *tmp);
if (!tmp) abort(); // handle alloc failure
names = tmp;
names[size - 1] = malloc(17 * sizeof(char));
strcpy(names[size - 1], v);
step.outputs[i] = size - 1;
}
else {
step.outputs[i] = idx;
}
}
//add step to list of temp
if (!temp) {
temp = malloc(sizeof(struct directive));
} else {
temp = realloc(temp, scount * sizeof(struct directive));
}
temp[scount - 1] = step;
}
// initialize values array
values = malloc(size * sizeof(int));
resetValues(size, values);
while(1 < 2) {
//print inputs
for (i = 0; i < icount; i++) {
printf("%d ", values[i + 2]);
}
printf("|");
//run through temp, calculate outputs
for (i = 0; i < scount; i++) {
struct directive step = temp[i];
if (strcmp(step.gate, "NOT") == 0) {
NOT(values, step.inputs[0], step.outputs[0]);
}
if (strcmp(step.gate, "AND") == 0) {
AND(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "OR") == 0) {
OR(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "NAND") == 0) {
NAND(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "NOR") == 0) {
NOR(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "XOR") == 0) {
XOR(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "PASS") == 0) {
PASS(values, step.inputs[0], step.outputs[0]);
}
if (strcmp(step.gate, "DECODER") == 0) {
DECODER(values, step.n, step.inputs, step.outputs);
}
if (strcmp(step.gate, "MULTIPLEXER") == 0) {
MUX(values, step.s, step.inputs, step.selectors, step.outputs[0]);
}
}
//print outputs
for (i = 0; i < ocount; i++) {
printf(" %d", values[icount + i + 2]);
}
printf("\n");
if (!incrementInputs(values, icount)) {
break;
}
}
for (i = 0; i < icount; i++) {
free(names[i + 2]);
}
for (i = 0; i < ocount; i++) {
free(names[i + icount + 2]);
}
for (int i = 0; i < scount; i++) {
free(temp[i].inputs);
free(temp[i].outputs);
free(temp[i].selectors);
}
free(names[0]);
free(names[1]);
//free(names[size-1]);
free(values);
free(temp);
free(names);
return 0;
}

Related

Memory leak when changing size of read input

I´m facing really weird issue with my headtail application. When I try to read from file data.txt using Powershell (command: Get-Content data.txt | .\Headtail.exe head 10) I always get proper and expected output. However if I change input from data.txt to fail.txt I won´t get any output from output function (called vypis()).
Does anyone have an idead what is going on here?
GOOD CASE: Output from command (this output is suppose to be same using fail.txt as an input (meaning that content of the given input should be printed)) Get-Content data.txt | .\Headtail.exe head 10 in PowerShell:
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
WRONG CASE: Output from command Get-Content fail.txt | .\Headtail.exe head 10 in PowerShell:
/*NOTHING */
Code for my headtail function is following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int const size = 15;
int last_changed = 0;
typedef struct {
char **field;
int *columns;
int rows;
} TMatrix;
void set_size(TMatrix* matrix) {
for (int i = 0; i < matrix->rows; i++) matrix->columns[i] = size;
}
TMatrix* allocate() {
TMatrix* matrix = malloc(sizeof(TMatrix));
if (!matrix) return NULL;
matrix->field = malloc(size * sizeof(char*));
if (!matrix->field) return NULL;
matrix->rows = size;
matrix->columns = malloc(size * sizeof(int));
if (!matrix->field) return NULL;
set_size(matrix);
for (int i = 0; i < matrix->rows; i++) {
matrix->field[i] = malloc(size * sizeof(char));
if (!matrix->field[i]) return NULL;
}
return matrix;
}
void release(TMatrix* matrix) {
for(int i = 0; i < matrix->rows; i++) free(matrix->field[i]);
free(matrix->field);
free(matrix->columns);
free(matrix);
}
bool add_rows(TMatrix* matrix) {
matrix->rows += 10;
char** rebuf = realloc(matrix->field, matrix->rows * sizeof(char*));
if (!rebuf) {
free(rebuf);
return false;
}
matrix->field = rebuf;
int* rebufl = realloc(matrix->columns, matrix->rows * sizeof(int));
if (!rebufl) {
free(rebufl);
return false;
}
matrix->columns = rebufl;
for (int i = 1; i <= 10; i++) {
char* rebuh = realloc(matrix->field[matrix->rows - i], size * sizeof(char));
if (!rebuh) {
free(rebuh);
return false;
}
matrix->field[matrix->rows - i] = rebuh;
matrix->columns[matrix->rows - i] = size;
}
return true;
}
bool add_column(TMatrix* matrix, int row) {
matrix->columns[row] += 15;
char* rebuf = realloc(matrix->field[row], matrix->columns[row] * sizeof(char));
if (!rebuf) {
free(rebuf);
return false;
}
matrix->field[row] = rebuf;
return true;
}
TMatrix* load(FILE* in) {
char c;
int actual_row = 0, actual_column = 0;
TMatrix* matrix;
if (!(matrix = allocate())) return NULL;
while ((fscanf(in, "%c", &c)) != EOF) {
matrix->field[actual_row][actual_column] = c;
if (c != '\n') {
actual_column += 1;
if (((matrix->columns[actual_row]) - 1) == actual_column) {
if (!add_column(matrix, actual_row)) return NULL;
}
}
else if (c == '\n') {
actual_column +=1;
if (((matrix->columns[actual_row]) - 1) == actual_column) {
if (!add_column(matrix, actual_row)) return NULL;
}
matrix->field[actual_row][actual_column] = '\0';
actual_column = 0;
actual_row += 1;
last_changed += 1;
if (((matrix->rows) - 1) == actual_row) {
if (!add_rows(matrix)) return NULL;
}
}
}
return matrix;
}
bool output(FILE* out, TMatrix *matrix, double num_of_output_lines, char method[]) {
if (!matrix) return false;
if (num_of_output_lines <= 0) return false;
if (matrix->rows <= 0) return false;
if (num_of_output_lines > last_changed) return false;
if (strcmp("head", method) == 0) {
for (int i = 0; i < num_of_output_lines; i++) {
for (int j = 0; j < matrix->columns[i]; j++) {
if (matrix->field[i][j] != '\0') fprintf(out, "%c", matrix->field[i][j]);
else break;
}
}
}
else if (strcmp("tail", method) == 0) {
for (int a = (last_changed-1); a >= (last_changed - num_of_output_lines); a--) {
for (int b = 0; b < matrix->columns[a]; b++) {
if (matrix->field[a][b] != '\0') fprintf(out, "%c", matrix->field[a][b]);
else break;
}
}
}
else return false;
return true;
}
void Help() {
fprintf(stdout, "-------------------------------------------------------------------------------------\n");
fprintf(stdout, "* Help function - nothing important *\n");
fprintf(stdout, "-------------------------------------------------------------------------------------\n");
}
int main(int argc, char *argv[])
{
if (argc < 3 || argc > 4) {
printf("!Valid count of arguments entered! \n");
return -1;
}
if (strcmp("-h", argv[1]) == 0) Help();
double num_of_output_lines = atoi(argv[argc - 1]);
TMatrix* matrix = load(stdin);
if (!matrix) {
printf("!Error while loading! \n");
return -1;
}
if (!output(stdout, matrix, num_of_output_lines, argv[argc - 2])) {
printf("!Error while printing! \n");
return -1;
}
release(matrix);
return 0;
}
And content of data.txt (works fine, just an example input):
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.
And finally content of fail.txt (didn´t get any output, the difference is just in length of some rows):
aaaaa.
bbbbbbb.
cccc.
ddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.

find the line which causes the segmentation fault, which I couldn't find

Currently I am writing a LZ77 algorithm. When I try to run my code, for some reason I get the ZSH segmentation fault. I've searched some topics but I couldn't find where to fix my code for this.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
/*#define pencereBoyutu 60
#define bufferBoyutu 40*/
typedef enum { false, true } bool;
// ============================================================================
int ortakBul(unsigned char window[], unsigned char str[], int strLen) {
int j, k, yer = -1;
int pencereBoyutu = 60;
for (int i = 0; i <= pencereBoyutu - strLen; i++) {
yer = k = i;
for (j = 0; j < strLen; j++) {
if (str[j] == window[k])
k++;
else
break;
}
if (j == strLen)
return yer;
}
return -1;
}
// ============================================================================
int compress(char* inputPath) {
FILE *fileInput;
FILE *fileOutput;
bool last = false;
int girisUzunlugu = 0;
int cikisUzunlugu = 0;
int setSonu = 0;
int yer = -1;
int i, size, shift, c_in;
size_t bytesRead = (size_t) -1;
int arrayBoyutu = 100;
int pencereBoyutu = 60;
int bufferBoyutu = 40;
unsigned char c;
unsigned char array[arrayBoyutu];
unsigned char window[pencereBoyutu];
unsigned char buffer[bufferBoyutu];
unsigned char bufferYukle[bufferBoyutu];
unsigned char str[bufferBoyutu];
// input out açmak
char path[30] = "";
strcat(path, inputPath);
fileInput = fopen(path, "rb");
fileOutput = fopen("output/output.lz77", "wb");
// mümkün değilse error ver
if (!fileInput) {
fprintf(stderr, "fileInput acilamiyor. %s", inputPath);
return 0;
}
// fileinput uzunluğunu çek
fseek(fileInput, 0, SEEK_END);
girisUzunlugu = ftell(fileInput);
fseek(fileInput, 0, SEEK_SET);
fprintf(stdout, "Giris dosyasi boyutu: %d byte", girisUzunlugu);
// dosya boşsa hata ver
if (girisUzunlugu == 0)
return 3;
// eğer dosya boyutu arrayboyutundan düşükse hata ver
if (girisUzunlugu < arrayBoyutu)
return 2;
// arrayı byte olarak oku
fread(array, 1, arrayBoyutu, fileInput);
fwrite(array, 1, pencereBoyutu, fileOutput);
// LZ77 mantığı
while (true) {
if ((c_in = fgetc(fileInput)) == EOF)
last = true;
else
c = (unsigned char) c_in;
for (int k = 0; k < pencereBoyutu; k++)
window[k] = array[k];
for (int k = pencereBoyutu, j = 0; k < arrayBoyutu; k++, j++) {
buffer[j] = array[k];
str[j] = array[k];
}
// en uzun ortak kelimeyi bulmak
if (setSonu != 0) {
size = bufferBoyutu - setSonu;
if (setSonu == bufferBoyutu)
break;
}
else {
size = bufferBoyutu;
}
yer = -1;
for (i = size; i > 0; i--) {
yer = ortakBul(window, str, i);
if (yer != -1)
break;
}
// hiç ortak bulunmaması halinde
if (yer == -1) {
fputc(255, fileOutput);
fputc(buffer[0], fileOutput);
shift = 1;
}
// ortak bulunması halinde
else {
fputc(pencereBoyutu - yer, fileOutput);
fputc(i, fileOutput);
if (i == bufferBoyutu) {
shift = bufferBoyutu + 1;
if (!last)
fputc(c, fileOutput);
else
setSonu = 1;
}
else {
if (i + setSonu != bufferBoyutu)
fputc(buffer[i], fileOutput);
else
break;
shift = i + 1;
}
}
// Shift buffer
for (int j = 0; j < arrayBoyutu - shift; j++)
array[j] = array[j + shift];
if (!last)
array[arrayBoyutu - shift] = c;
if (shift == 1 && last)
setSonu++;
if (shift != 1) {
// yeni bitler oku
bytesRead = fread(bufferYukle, 1, (size_t) shift - 1, fileInput);
// yeni bitleri arraya yükle
for (int k = 0, l = arrayBoyutu - shift + 1; k < shift - 1; k++, l++)
array[l] = bufferYukle[k];
if (last) {
setSonu += shift;
continue;
}
if (bytesRead < shift - 1)
setSonu = shift - 1 - bytesRead;
}
}
// fileoutput uzunluğunu çek
fseek(fileOutput, 0, SEEK_END);
cikisUzunlugu = ftell(fileOutput);
fseek(fileOutput, 0, SEEK_SET);
fprintf(stdout, "\nCikis dosya boyutu: %d byte\n", cikisUzunlugu);
// I/O dosyaları kapanması
fclose(fileInput);
fclose(fileOutput);
return 1;
}
// ============================================================================
// Decompress
int decompress() {
FILE *fileInput;
FILE *fileOutput;
int shift, denge, ortak, c_in;
bool done = false;
int pencereBoyutu = 60;
int bufferBoyutu = 40;
int arrayBoyutu = pencereBoyutu + bufferBoyutu;
unsigned char c;
unsigned char window[pencereBoyutu];
unsigned char writeBuffer[pencereBoyutu];
unsigned char readBuffer[2];
// i/o dosyalarin acilmasi
fileInput = fopen("output/output.lz77", "rb");
fileOutput = fopen("output/file", "wb");
if (!fileInput) {
fprintf(stderr, "fileInput açılamıyor. %s", "output.lz77");
return 0;
}
fread(window, 1, pencereBoyutu, fileInput);
fwrite(window, 1, pencereBoyutu, fileOutput);
// decompress mantığı
while (true) {
size_t bytesRead = fread(readBuffer, 1, 2, fileInput);
if (bytesRead >= 2) {
denge = (int) readBuffer[0];
ortak = (int) readBuffer[1];
if (denge == 255) {
denge = 0;
c = (unsigned char) ortak;
ortak = 0;
shift = ortak + 1;
}
else {
shift = ortak + 1;
c_in = fgetc(fileInput);
if (c_in == EOF)
done = true;
else
c = (unsigned char) c_in;
}
for (int i = 0, j = pencereBoyutu - denge; i < ortak; i++, j++)
writeBuffer[i] = window[j];
fwrite(writeBuffer, 1, (size_t) ortak, fileOutput);
if (!done)
fputc(c, fileOutput);
// Shift window
for (int i = 0; i < pencereBoyutu - shift; i++)
window[i] = window[i + shift];
for (int i = 0, j = pencereBoyutu - shift; i < ortak; i++, j++)
window[j] = writeBuffer[i];
window[pencereBoyutu - 1] = c;
}
else {
break;
}
}
// dosyaları kapat
fclose(fileInput);
fclose(fileOutput);
return 1;
}
// ============================================================================
int main(int argc, char* argv[]) {
clock_t begin = clock();
if (argc < 2) {
printf("2 argüman gerekiyor: [-c|-d] [dosya_yolu]");
} else {
// decompress
if (strcmp(argv[1], "-d") == 0) {
int result = decompress();
if (result == 0) {
fprintf(stderr, "\nSikistirma islemi HATALI");
} else if (result == 1) {
printf("\nSikistirma islemi OK");
}
}
// compress
else if (strcmp(argv[1], "-c") == 0) {
int result = compress(argv[2]);
if (result == 0) {
fprintf(stderr, "\nSikistirma islemi HATALI\n");
} else if (result == 1) {
printf("\nSikistirma islemi OK");
} else if (result == 2) {
fprintf(stderr, "\nDosya cok kucuk.\n");
} else if (result == 3) {
fprintf(stderr, "\nDosya bos.\n");
}
} else {
printf("Gecersiz argumanlar.");
}
}
// calistirma zamanını bastırmak
clock_t end = clock();
printf("\n\nCalistirma zamani: ");
printf("%f", ((double) (end - begin) / CLOCKS_PER_SEC));
printf(" [saniye]");
return 0;
}
// ============================================================================
After compiling you have to give arguments for running:
./lz77 -c input.txt
when I try to run my application with the input above which has 100 characters in it, it gives me segmentation fault. I couldn't find any reason after done some research about it. I'll be so happy if anyone can help.

Removing Garbage value in array in C

I have a garbage problem in my array in C, that I can't solve and I have used the memset function for this but this is not useful to me. how can I solve this problem. If I run this code in Code Block or other PC then this is not run completely.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
int main() {
clrscr();
int a, b, len = 0, x, i = 0, j, match, misMatch, gapPenalty, sim, m1, m2, m3;
char ch;
char *seq1 = (char *)malloc(100 * sizeof(char));
char *seq2 = (char *)malloc(100 * sizeof(char));
char *s1 = (char *)malloc(100 * sizeof(char));
char *s2 = (char *)malloc(100 * sizeof(char));
/*memset(seq1, 0, strlen(seq1) - 1);
memset(seq2, 0, strlen(seq2) - 1);
memset(s1, 0, strlen(s1) - 1);
memset(s2, 0, strlen(s2) - 1);*/
int **matrix;
int **back;
FILE *inputFile;
inputFile = fopen("in.txt", "r");
printf("Enter Match Point : ");
scanf("%d", &match);
printf("Enter Mismatch Point : ");
scanf("%d", &misMatch);
printf("Enter Gap Point : ");
scanf("%d", &gapPenalty);
while (fscanf(inputFile,"%s\n%s", seq1, seq2) != EOF);
a = strlen(seq1);
b = strlen(seq2);
for (j = 0; j <= strlen(seq2); j++) {
for (i = 0; i <= strlen(seq1); i++) {
if (i == 0 || j == 0) {
if (i == 0) {
matrix[j][i] = j * gapPenalty;
back[j][i] = 0;
}
if (j == 0) {
matrix[j][i] = i * gapPenalty;
back[j][i] = 0;
}
} else {
if (seq1[i - 1] == seq2[j - 1]) {
sim = match;
} else {
sim = misMatch;
}
m1 = matrix[j - 1][i - 1] + sim;
m2 = matrix[j - 1][i] + gapPenalty;
m3 = matrix[j][i - 1] + gapPenalty;
if (m1 > m2) {
if (m1 > m3) {
matrix[j][i] = m1;
back[j][i] = 1;
} else {
matrix[j][i] = m3;
back[j][i] = 3;
}
} else {
if (m2 > m3) {
matrix[j][i] = m2;
back[j][i] = 2;
} else {
matrix[j][i] = m3;
back[j][i] = 3;
}
}
}
}
}
printf("%s", seq1);
printf("\n");
printf("%s", seq2);
printf("\n");
if (a > b) {
len = a;
} else {
len = b;
}
for (x = 0; x < len; x++) {
if (back[b][a] == 1) {
s1[x] = seq1[a - 1];
s2[x] = seq2[b - 1];
a = a - 1;
b = b - 1;
} else if(back[b][a] == 2) {
s1[x] = seq1[a - 1];
s2[x] = '-';
a = a - 1;
} else {
s1[x] = '-';
s2[x] = seq2[b - 1];
b = b - 1;
}
}
for (j = 0; j <= strlen(seq2); j++) {
for (i = 0; i <= strlen(seq1); i++) {
printf("%d ", matrix[j][i]);
}
printf("\n");
}
printf("\n");
for (j = 0; j <= strlen(seq2); j++) {
for (i = 0; i <= strlen(seq1); i++) {
printf("%d ", back[j][i]);
}
printf("\n");
}
printf("\n");
printf("%s", s1);
printf("\n");
printf("%s", s2);
printf("\n");
free(s1);
free(s2);
free(matrix);
free(back);
getch();
return 0;
}
Use calloc(). calloc() initializes all the allocated memory to 0.
// sizeof (char), by definition, is 1
char *seq1 = calloc(100, 1);
char *seq2 = calloc(100, 1);
char *s1 = calloc(100, 1);
char *s2 = calloc(100, 1);
The immediate problem with your commented code is that you cannot apply strlen() to an uninitialized array. You should be using the correct size (which you just used a few statements before) instead
/*memset(seq1, 0, 100);
memset(seq2, 0, 100);
memset(s1, 0, 100);
memset(s2, 0, 100);*/

Double free/corruption?

typedef struct {
int *info;
} row;
struct {
row* head;
int len;
int size;
} list;
int main{
list.len = 0;
list.size = 1;
list.head = malloc(list.size * sizeof(row));
//...... some other code that calls addRow (list.len) times
for (i = list.len - 1; i > 0; i--) {
free(list.head[i].info);/*****HERE**********/
}
free(list.head);
}
void addRow(int* data) {
int i;
if (list.len == list.size) {
row *temp = malloc(sizeof(row) * list.size * 2);
if (temp == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < list.len; i++) {
temp[i] = list.head[i];
}
free(list.head);
list.head = temp;
}
list.head[list.len].info = malloc(sizeof(int) * numCols);
for (i = 0; i < numCols; i++) {
list.head[list.len].info[i] = data[i];
}
list.len++;
}
This is the code that I used to addRow is were I malloc all the data. and I don't see why I'm getting a double free/ corruption error. At the area I marked HERE, I believe I am malloc-ing for all instances of info in the row struct, These line are the only ones doing malloc/free.
I just want to get into the habit free-ing properly when terminating the program.
FULL PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct {
int *info;
} row;
struct {
row* head;
int len;
int size;
} list;
static int sortCol, numCols;
int qSortCompare(const void*, const void*);
void printList();
int processInput();
void nullify(char*, int);
int main(int n, char **args) {
sortCol = 1;
numCols = 0;
if (n > 1 && args[1][0] == '-' && args[1][1] == 'c') {
sortCol = atoi(args[2]);
}
list.len = 0;
list.size = 1;
list.head = malloc(list.size * sizeof(row));
processInput();
if (sortCol < 1 || sortCol > numCols) {
fprintf(stderr, "Error (enter): (Line ##) Invalid column to sort.\n");
return 1;
}
printList();
qsort(list.head, list.len, sizeof(row), &qSortCompare);
printf("\n");
printList();
int i;
printf("add1:%p\nadd2:%p\n", list.head[0].info, list.head[1].info);
for (i = 0; i < list.len; i++) {
free(list.head[i].info);
}
free(list.head);
return 0;
}
void nullify(char* str, int n) {
int i;
for (i = 0; i < n; i++)
str[i] = '\0';
}
int parseInt(char *str, int index) {
int num = -1;
sscanf(str + index, "%d", &num);
return num;
}
void addRow(int* data) {
int i;
if (list.len == list.size) {
row *temp = malloc(sizeof(row) * list.size * 2);
if (temp == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < list.len; i++) {
temp[i] = list.head[i];
}
free(list.head);
list.head = temp;
}
list.head[list.len].info = malloc(sizeof(int) * numCols);
if (list.head[list.len].info == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < numCols; i++) {
list.head[list.len].info[i] = data[i];
}
list.len++;
}
int processInput() {
int i, maxChars = 200, totalN = 0;
int *nums, curNumIndex = 0, onNum, curNum;
numCols = maxChars / 2;
nums = (int*) (malloc(sizeof(int) * numCols));
char str[maxChars], ch;
for (i = 0; i < numCols; i++) {
nums[i] = -1;
}
while (!feof(stdin)) {
nullify(str, maxChars);
fgets(str, maxChars, stdin);
onNum = isdigit(str[0]);
curNumIndex = 0;
for (i = 0; i < maxChars; i++) {
ch = str[i];
if ((!isspace(ch)) && (!isdigit(ch)) && (ch != '\0')) {
fprintf(stderr, "Error 1: (Line ##) Invalid char in input.\n");
//return 0;
}
if (isspace(ch) && onNum) {
curNum = parseInt(str, curNumIndex);
curNumIndex = i;
nums[totalN % numCols] = curNum;
totalN++;
if (totalN % numCols == 0)
addRow(nums);
} else {
onNum = isdigit(str[i]);
}
if (ch == '\n' || ch == '\0')
break;
}
if (numCols > totalN) {
if (totalN > 0) {
numCols = totalN;
addRow(nums);
} else {
fprintf(stderr,
"Error (enter): (Line ##) Invalid first line of input.\n");
}
}
if (ch != '\n' && ch != '\0') {
fprintf(stderr,
"Error (enter): (Line ##) A row from input too long.\n");
//return 0;
}
}
return 1;
}
int qSortCompare(const void *c1, const void *c2) {
row *t1, *t2;
t1 = (row*)c1;
t2 = (row*)c2;
return t1->info[sortCol - 1] - t2->info[sortCol - 1];
}
void printList() {
int i, j;
for (i = 0; i < list.len; i++) {
for (j = 0; j < numCols; j++) {
printf("%10d ", list.head[i].info[j]);
}
printf("\n");
}
}
Program needs a EOF terminated input of integer numbers. Specifically with the same number of integers before the newline.
UPDATE: I used gdb to analysis the free part i it only fails on the second iteration, using for(i = 0; i < list.len; i++) and for(i = list.len - 1; i > 0 ; i--)
Another thing is that I don't see the update to list.size (it should be updated when resizing head)
"I just want to get into the habit free-ing properly when terminating the program."
The correct way to handle things like this is to free a non-NULL pointer and then set the pointer to NULL.
For example:
int* x = malloc (sizeof (int));
if (x != NULL) {
free (x);
x = NULL;
}
/* Misc. Code ... */
/* Now for whatever reason, you want to free x again */
/* This branch is never triggered, because you were smart enough to set x to NULL
* when you freed it the first time...
*/
if (x != NULL) {
free (x);
x = NULL;
}

Segfault on fscanf

filenamelists is a struct with two file pointers. merge mergesorts these two fileptrs. I'm getting a segfault on the while(fscanf(filenamelist[0].file1, "%d", &chd) != EOF). I think its because I'm not implementing pthread correctly. Ive been trying to debug forever so any help would be appreciated. tempf is a file ptr to the mergesorted arrays. It is rewinded in the merge function itself.
for(i=0; i<size; i++)
{
if(argc==1)
{
char* tedious2 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
strcpy(tedious2,argv[i+1]);
filenamelist[i].file1 = fopen(strcat(tedious2,".sorted"),"r");
filenamelist[i].file2 = NULL;
filenamelist[i].alone = 1;
free(tedious2);
break;
}
else if(size-1 ==i && size%2 != 0)
{
char* tedious1 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
strcpy(tedious1,argv[i+1]);
filenamelist[i].file1 = fopen(strcat(tedious1,".sorted"),"r");
filenamelist[i].file2 = NULL;
filenamelist[i].alone = 1;
free(tedious1);
}
else
{
char* tedious3 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
strcpy(tedious3,argv[i+1]);
char* tedious4 = (char*) malloc((strlen(argv[i+2]+7))*sizeof(char));
strcpy(tedious4,argv[i+2]);
filenamelist[i].file1 = fopen(strcat(tedious3,".sorted"),"r");
filenamelist[i].file2 = fopen(strcat(tedious4,".sorted"),"r");
filenamelist[i].alone = 0;
free(tedious3);
free(tedious4);
}
}
// pthread_t* threadid2;
// threadid2 = (pthread_t*) malloc(sizeof(pthread_t)*(2*argc));
while(size>=0)
{
i = 0;
pthread_t* threadid2;
threadid2 = (pthread_t*) malloc(sizeof(pthread_t)*size);
for ( ; i<size;i++ )
{
pthread_create(&threadid2[i], NULL, merge, &filenamelist[i]);
}
i = 0;
for ( ; i<size; i++)
{
pthread_join(threadid2[i], tempf);
if (i%2 == 0)
{
filenamelist[i/2].file1 = tempf;
}
else
{
filenamelist[i/2].file2 = tempf;
}
}
zit=0;
truth = 0;
while(zit<z)
{
if(inputFiles[zit] == tempf)
truth = 1;
zit++;
}
if(truth != 1)
{
inputFiles[z] = tempf;
z++;
}
if(size==1)
size = 0;
else if (size % 2 == 0)
size = size/2;
else
size = (size/2)+1;
free(threadid2);
}
int chd = 0;
// if(0!=feof(tempf))
// rewind(tempf);
//rewind(filenamelist[0]->file1);
int finish = 0;
//printf("file 1:%p",tempf);
while(fscanf(filenamelist[0].file1, "%d", &chd) != EOF)
finish++;
rewind(filenamelist[0].file1);
int* finarr = (int*) malloc(finish*sizeof(int));
int xx =0;
for(;fscanf(filenamelist[0].file1, "%d", &chd) != EOF; xx++)
finarr[xx] = chd;
tempf is declared at start of func as FILE* tempf;
char* tedious2 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
Make that:
char *tedious2 = malloc( strlen(argv[i+1]) + strlen(".sorted") + 1 );

Resources