Heap-corruption when freeing allocated memory - c

I am writing small school project, and I got stuck with error that I can't fix. When I try to free allocated memory, I get this error:
Here is the code that involves my char pointer temp:
1. Allocation of memory and setting starting value:
char *temprijec(int rng, RIJEC *B, int *len) {
int i;
char *temp=(char*)calloc(*len + 1, sizeof(char));
*len = strlen((B + rng)->rijec);
for (i = 0; i < *len; i++) {
if (i == 0) {
temp[i] = (B + rng)->rijec[i];
}
else if (i == (*len)) {
temp[i] = '\0';
}
else {
temp[i] = '_';
}
}
return temp;
}
2. Working with char pointer temp:
void tijek_igre(char*temp,RIJEC *B,int rng,int len,int*br2pok,int *pokpogreska,int *pokbr,char*pokch) {
int i;
printf("\nPogodi slovo ili rijec!");
*pokch = _getch();
for (i = 0; (B + rng)->rijec[i] != '\0'; i++) {
if (*pokch == (B + rng)->rijec[i]) {
temp[i] = *pokch;
}
}
for (i = 0; (B + rng)->rijec[i] != '\0'; i++) {
if (*pokch != (B + rng)->rijec[i]) {
(*br2pok)++;
if (*br2pok == len) {
(*pokpogreska)++;
}
}
}
for (i = 0; temp[i] != '\0'; i++) {
if (temp[i] != '_') {
(*pokbr)++;
}
}
}
Everything is fine until I try to free it with free(temp);

I fixed the error by changing the way I am passing variables to function,structure instead of pointers and now it works idk why but it works :).Tnx everyone for help.
Changed code:
VARIJABLE temprijec(VARIJABLE V, RIJEC *B) {
int i;
V.len = strlen((B + V.rng)->rijec);
V.temp = (char*)calloc(V.len + 1, sizeof(char));
for (i = 0; i < V.len + 1; i++) {
if (i == 0) {
V.temp[i] = (B + V.rng)->rijec[i];
}
else if (i == (V.len)) {
V.temp[i] = '\0';
}
else {
V.temp[i] = '_';
}
}
return V;
}
and
VARIJABLE tijek_igre(RIJEC *B, VARIJABLE V) {
int i;
printf("\nPogodi slovo ili rijec!");
V.ch = _getch();
for (i = 0; (B + V.rng)->rijec[i] != '\0'; i++) {
if (V.ch == (B + V.rng)->rijec[i]) {
V.temp[i] = V.ch;
}
}
for (i = 0; (B + V.rng)->rijec[i] != '\0'; i++) {
if (V.ch != (B + V.rng)->rijec[i]) {
(V.pogresno_slovo)++;
if (V.pogresno_slovo == V.len) {
(V.pogreska)++;
}
}
}
for (i = 0; V.temp[i] != '\0'; i++) {
if (V.temp[i] != '_') {
(V.tocno_slovo)++;
}
}
return V;
}

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.

Checking NULL pointer segmentation fault in C

I have to split an initial char and create a list of said char which has to end with a NULL so i can iterate over in the main without knowing list size. The problem is that i get a seg fault whenever i try to check if last element is NULL. i am sorry i am still trying to learn both C and english. Thank you all
#include <stdlib.h>
#include <stdio.h>
char **split(const char *s) {
char **split;
unsigned m_size = 0, c_size, i, j, k;
// get s size
for (i = 0; s[i] != '\0'; i++) {
if (s[i] == ' ') {
m_size++;
}
}
m_size++;
split = (char**) malloc(sizeof(char) * (m_size + 1));
int sizes[m_size];
c_size = 0;
// get s words size
for (i = 0, j = 0; s[i] != '\0'; i++) {
if (s[i] == ' ') {
c_size++;
sizes[j] = c_size;
c_size = 0;
j++;
} else {
c_size++;
}
}
sizes[j] = c_size;
for (i = 0; i < m_size; i++) {
split[i] = (char *) malloc(sizeof(char) * sizes[i]);
}
split[i] = NULL;
for (i = 0, j = 0, k = 0; s[i] != '\0'; i++) {
if (s[i] != ' ') {
split[j][k] = s[i];
k++;
} else {
split[j][k] = '\0';
j++;
k = 0;
}
}
return split;
}
int main() {
char s[19] = "hello how are you?";
char **splitted;
unsigned i;
splitted = split(s);
if (splitted == NULL) {
return 1;
}
for (i = 0; splitted[i]!=NULL; i++) {
printf("%s\n", splitted[i]);
}
return 0;
}
EDIT
#include <stdlib.h>
#include <stdio.h>
char **split(const char *s) {
char **r;
unsigned word_size = 0;
unsigned list_size = 0, i, j, k;
// get s size
for (i = 0; s[i] != '\0'; i++) {
if (s[i] != ' ') {
word_size++;
} else {
if (word_size > 0) {
list_size++;
word_size = 0;
}
}
}
list_size++;
r = malloc(sizeof(*r) * (list_size + 1));
int char_sizes[list_size];
for (i = 0; i < list_size; char_sizes[i] = 0, i++);
// get s words size
for (i = 0, j = 0; s[i] != '\0'; i++) {
if (s[i] != ' ') {
char_sizes[j]++;
} else {
if (char_sizes[j] > 0) {
j++;
}
}
}
for (i = 0; i < list_size; i++) {
r[i] = malloc(sizeof(char) * char_sizes[i]);
}
r[i] = NULL;
for (i = 0, j = 0, k = 0; s[i] != '\0'; i++) {
if (s[i] != ' ') {
r[j][k] = s[i];
k++;
} else {
if (k > 0) {
r[j][k] = '\0';
j++;
k = 0;
}
}
}
return r;
}
void destroy(char **list) {
unsigned i;
for (i = 0; list[i] != NULL; i++) {
free(list[i]);
}
free(list);
}
int main() {
char s[100] = " hello guys how are? you,d 31 3 ";
char **splitted;
unsigned i;
splitted = split(s);
if (splitted == NULL) {
return 1;
}
for (i = 0; splitted[i]!=NULL; i++) {
printf("%s", splitted[i]);
}
destroy(splitted);
return 0;
}
ok guys i followed your tips and i edited my code. leaving this here if someone wants to point out other errors i will appreciate. now it should work even with multiple spaces. thanks to all
Your are requesting an "array" of pointers to char, but you are allocating an "array" of chars:
split = (char**) malloc(sizeof(char) * (m_size + 1));
should become
split = malloc(sizeof(char*) * (m_size + 1));
Note the sizeof(char*). BTW: Note that in C, you should not cast the result of malloc as explained in this SO post.

Why does 'a' prematurely end this loop?

Pointers rather than straight answers if you will please.
This loop does some manipulation on chars and outputs a ciphertext c based on a key k and some plaintext p.
When 'a' or 'A' comes up in the plaintext, the program will output that letter as expected but then end the loop prematurely.
p suddenly becomes just one character long, this character being 1.
while (i < strlen(p))
{
char stdp = p[i];
char stdk = k[j];
if (isalpha(stdp))
{
if (islower(stdp))
{
p[i] = stdp - 'a';
Aa = 0;
}
else
{
p[i] = stdp - 'A';
Aa = 1;
}
if (islower(k[j]))
{
k[j] = stdk - 'a';
}
else
{
k[j] = stdk - 'A';
}
}
if (isalpha(stdp))
{
c[i] = ((p[i] + k[j]) % 26);
}
else
{
c[i] = p[i];
}
if (isalpha(stdp))
{
if (Aa == 1)
{
c[i] = c[i] + 'A';
}
else if (Aa == 0)
{
c[i] = c[i] + 'a';
}
}
if (isalpha(stdp))
{
if (j + 1 == kk)
{
j = (j + 1) % kk;
strcpy(k, argv[1]);
}
else
{
j++;
}
}
i++;
}
I have now solved the issues I was facing with the program terminating early.
Most of the issues seem to have been solved by stopping the constant refs to strlen(p) and just assigning that to a static variable. I have tried to tidy up the code as suggested.
int main(int argc, char *argv[])
{
if (argc != 2 || argv[1] == NULL)//no more than 1 arg and not empty
{
printf("Command requires one argument to run.\n");
return 1;
}
char *k = malloc(100);
strcpy(k, argv[1]);
int kInt = strlen(k);
for (int i = 0, n = kInt; i < n ; i++)// iterating though the key to check it is alphabetic
{
if (isalpha(k[i]) == false)
{
printf("Make sure key is alphabetic!\n");
return 1;
}
}
printf ("plaintext: ");
char *p = malloc(100);
strcpy(p, get_string());
int pInt = strlen(p);
int i = 0;
int j = 0;
int Aa = 0;
char *c = malloc(100);
while (j < kInt)
{
if (islower(k[j]))
{
k[j] = k[j] - 'a';
}
else
{
k[j] = k[j] - 'A';
}
j++;
}
j = 0;
while (i < pInt)
{
if (isalpha(p[i]))
{
if (islower(p[i]))
{
p[i] = p[i] - 'a';
Aa = 0;
}
else
{
p[i] = p[i] - 'A';
Aa = 1;
}
c[i] = ((p[i] + k[j]) % 26);
if (Aa == 1)
{
c[i] = c[i] + 'A';
}
else if (Aa == 0)
{
c[i] = c[i] + 'a';
}
if (j + 1 == kInt)
{
j = (j+1) % kInt;
}
else
{
j++;
}
}
else if (isalpha(p[i]) != true)
{
c[i] = p[i];
}
i++;
}
printf("ciphertext: %s\n", c);
free(c);
free(k);
free(p);
}

Printing string pointers in c

So, essentially I have two files:
File 1:
//
// main.c
// frederickterry
//
// Created by Rick Terry on 1/15/15.
// Copyright (c) 2015 Rick Terry. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int size (char *g) {
int ofs = 0;
while (*(g+ofs) != '\0') {
++ofs;
}
return ofs;
}
int parse(char *g) {
// Setup
char binaryConnective;
int negated = 0;
// Looking for propositions
int fmlaLength = size(g);
if(fmlaLength == 0) {
return 1;
}
if(fmlaLength == 1) {
if(g[0] == 'p') {
return 1;
} else if (g[0] == 'q') {
return 1;
} else if (g[0] == 'r') {
return 1;
} else {
return 0;
}
}
// Now looking for negated preposition
if(fmlaLength == 2) {
char temp[100];
strcpy(temp, g);
if(g[0] == '-') {
negated = 1;
int negatedprop = parse(g+1);
if(negatedprop == 1) {
return 2;
}
}
}
// Checking if Binary Formula
char arrayleft[50];
char arrayright[50];
char *left = "";
char *right = "";
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
if(fmlaLength != 1 && fmlaLength != 2) {
if(g[0] == '-') {
int negatedBinary = parse(g+1);
if(negatedBinary == 1 || negatedBinary == 2 || negatedBinary == 3) {
return 2;
} else {
return 0;
}
}
int i = 0;
int l = 0;
int p = strlen(g);
for(l = 0; l < strlen(g)/2; l++) {
if(g[l] == '(' && g[p-l-1] == ')') {
i++;
}
}
for(int q = i; q < strlen(g); q++) {
if(g[q] == '(') {
numLeft++;
} else if(g[q] == ')') {
numRight++;
}
arrayleft[q] = g[q];
//printf("%c", arrayleft[i]);
//printf("%s", left);
if((numRight == numLeft) && (g[q+1] == 'v' || g[q+1] == '>' || g[q+1] == '^')) {
arrayleft[q+1] = '\0';
bclocation = q+1;
binaryConnective = g[q+1];
binarypresent = 1;
// printf("The binary connecive is: %c\n", binaryConnective);
break;
}
}
if(binarypresent == 0) {
return 0;
}
int j = 0;
for(int i = bclocation+1; i < strlen(g)-1; i++) {
arrayright[j] = g[i];
j++;
}
arrayright[j] = '\0';
left = &arrayleft[1];
right = &arrayright[0];
//printf("Printed a second time, fmla 1 is: %s", left);
int parseleft = parse(left);
// printf("Parse left result: %d\n", parseleft);
if(parseleft == 0) {
return 0;
}
int parseright = parse(right);
if(parseright == 0) {
return 0;
}
// printf("Parse right result: %d\n", parseleft);
if(negated == 1) {
return 2;
} else {
return 3;
}
}
return 0;
}
int type(char *g) {
if(parse(g) == 1 ||parse(g) == 2 || parse(g) == 3) {
if(parse(g) == 1) {
return 1;
}
/* Literals, Positive and Negative */
if(parse(g) == 2 && size(g) == 2) {
return 1;
}
/* Double Negations */
if(g[0] == '-' && g[1] == '-') {
return 4;
}
/* Alpha & Beta Formulas */
char binaryConnective;
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
bclocation = i+1;
binaryConnective = g[i+1];
binarypresent = 1;
break;
}
}
}
/* Connective established */
if(binaryConnective == '^') {
if(g[0] == '-') {
return 3;
} else {
return 2;
}
} else if(binaryConnective == '>') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
} else if (binaryConnective == 'v') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
}
}
return 0;
}
char bin(char *g) {
char binaryConnective;
char arrayLeft[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
int j = 0;
arrayLeft[j++] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[i+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
return binaryConnective;
}
}
}
return binaryConnective;
}
char *partone(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
for(int k = bclocation+1; k < strlen(g)-1; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
int k = 0;
k++;
return leftSide;
}
char *parttwo(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
int n = size(g) - 1;
if(g[strlen(g)-1] != ')') {
n++;
}
for(int k = bclocation+1; k < n; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
char* rightSide = &arrayRight[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
return rightSide;
}
char *firstexp(char *g) {
char* left = partone(g);
char leftArray[50];
int i = 0;
for(i; i < strlen(left); i++) {
leftArray[i] = left[i];
}
leftArray[i] = '\0';
char binConnective = bin(g);
int typeG = type(g);
if(typeG == 2) {
if(binConnective == '^') {
return &leftArray;
} else if(binConnective == '>') {
return &leftArray;
}
} else if(typeG == 3) {
if(binConnective == 'v')
return &leftArray;
}
char temp[50];
for(int i = 0; i < strlen(leftArray); i++) {
temp[i+1] = leftArray[i];
}
temp[0] = '-';
char* lefttwo = &temp[0];
if(typeG == 2) {
if(binConnective == 'v') {
return lefttwo;
}
} else if(typeG == 3) {
if(binConnective == '>' || binConnective == '^') {
return lefttwo;
}
}
return "Hello";
}
char *secondexp(char *g) {
// char binaryConnective = bin(g);
// char* right = parttwo(g);
// char rightArray[50];
// int i = 0;
// for(i; i< strlen(right); i++) {
// rightArray[i+1] = right[i];
// }
// rightArray[i] = '\0';
// int typeG = type(g);
// if(type(g) == 2) {
// if(binaryConnective == '^') {
// return &rightArray;
// }
// } else if(type(g) == 3) {
// if(binaryConnective == 'v' || binaryConnective == '>') {
// return &rightArray;
// }
// }
return "Hello";
}
typedef struct tableau tableau;
\
\
struct tableau {
char *root;
tableau *left;
tableau *right;
tableau *parent;
int closedbranch;
};
int closed(tableau *t) {
return 0;
}
void complete(tableau *t) {
}
/*int main(int argc, const char * argv[])
{
printf("Hello, World!\n");
printf("%d \n", parse("p^q"));
printf("%d \n", type("p^q"));
printf("%c \n", bin("p^q"));
printf("%s\n", partone("p^q"));
printf("%s\n", parttwo("p^q"));
printf("%s\n", firstexp("p^q"));
printf("Simulation complete");
return 0;
}*/
File 2:
#include <stdio.h>
#include <string.h> /* for all the new-fangled string functions */
#include <stdlib.h> /* malloc, free, rand */
#include "yourfile.h"
int Fsize = 50;
int main()
{ /*input a string and check if its a propositional formula */
char *name = malloc(Fsize);
printf("Enter a formula:");
scanf("%s", name);
int p=parse(name);
switch(p)
{case(0): printf("not a formula");break;
case(1): printf("a proposition");break;
case(2): printf("a negated formula");break;
case(3): printf("a binary formula");break;
default: printf("what the f***!");
}
printf("\n");
if (p==3)
{
printf("the first part is %s and the second part is %s", partone(name), parttwo(name));
printf(" the binary connective is %c \n", bin(name));
}
int t =type(name);
switch(t)
{case(0):printf("I told you, not a formula");break;
case(1): printf("A literal");break;
case(2): printf("An alpha formula, ");break;
case(3): printf("A beta formula, ");break;
case(4): printf("Double negation");break;
default: printf("SOmewthing's wrong");
}
if(t==2) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
if(t==3) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
tableau tab;
tab.root = name;
tab.left=0;
tab.parent=0;
tab.right=0;
tab.closedbranch=0;
complete(&tab);/*expand the root node then recursively expand any child nodes */
if (closed(&tab)) printf("%s is not satisfiable", name);
else printf("%s is satisfiable", name);
return(0);
}
If you look at the first file, you'll see a method called * firstexp(char * g).
This method runs perfectly, but only if another method called * secondexp(char * g) is commented out.
If * secondexp(char * g) is commented out, then *firstexp runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is -(pvq), second expansion fmla is Hello
((pvq)>-p) is satisfiableProgram ended with exit code: 0
otherwise, if *secondexp is not commented out, it runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is \240L, second expansion fmla is (-
((pvq)>-p) is satisfiable. Program ended with exit code: 0
As you can see, the outputs are completely different despite the same input. Can someone explain what's going on here?
In the commented-out parts of secondexp and in parttwo, you return the address of a local variable, which you shouldn't do.
You seem to fill a lot of ad-hoc sized auxiliary arrays. These have the problem that they might overflow for larger expressions and also that you cannot return them unless you allocate them on the heap with malloc, which also means that you have to free them later.
At first glance, the strings you want to return are substrings or slices of the expression string. That means that the data for these strings is already there.
You could (safely) return pointers into that string. That is what, for example strchr and strstr do. If you are willing to modify the original string, you could also place null terminators '\0' after substrings. That's what strtok does, and it has the disadvantage that you lose the information at that place: If you string is a*b and you modify it to a\0b, you will not know which operator there was.
Another method is to create a struct that stores a slice as pointer into the string and a length:
struct slice {
const char *p;
int length;
};
You can then safely return slices of the original string without needing to worry about additional memory.
You can also use the standard functions in most cases, if you stick to the strn variants. When you print a slice, you can do so by specifying a field width in printf formats:
printf("Second part: '%.*s'\n", s->length, s->p);
In your parttwo() function you return the address of a local variable
return rightSide;
where rightSide is a pointer to a local variable.
It appears that your compiler gave you a warning about this which you solved by making a pointer to the local variabe arrayRight, that may confuse the compiler but the result will be the same, the data in arrayRight will no longer exist after the function returns.
You are doing the same all over your code, and even worse, in the secondexp() function you return a the address of a local variable taking it's address, you are not only returning the address to a local variabel, but also with a type that is not compatible with the return type of the function.
This is one of many probable issues that your code may have, but you need to start fixing that to continue with other possible problems.
Note: enable extra warnings when compiler and listen to them, don't try to fool the compiler unless you know exactly what you're doing.

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;
}

Resources