Quick summary - I am testing my functions, and for that, I've decided to write my own add_as_first() and add_as_last() functions, which are adding character to the old string array, through creating a new one and making a copy, without using default c language string functions. And for some reason, one out of two string arrays isn't behaving like I would like it to do. I've added strlen() function for debugging and I can see that inside a print_file function my string array is perfectly healthy and growing bigger as the function goes through its cycles. But for some reason, when the function ends, one of the string "res" is back to 0 length, while, the second string, "body", got properly mutated and has a value which is supposed to have. The difference between them is that "res" is getting filled by using add_as_last() function inside a print_file loop function, while, "body" is getting filled by using add_as_first() function inside a forming_list() function, which is inside print_file(). Any idea why it behaves this way? It looks like scoping issues but it should work properly, considering that both "body" and "res" are being used in about the same way.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define x_size 4
#define y_size 4
char* add_as_first(char *given_arr, char given_char, int check) {
int strLen = 0;
while (given_arr[strLen] != '\0') {
strLen++;
}
char *new_arr;
new_arr = (char*)malloc((strLen + 1 + 1) * sizeof(char));
new_arr[0] = given_char;
int i = 0;
for (; i < strLen; i++) {
new_arr[i + 1] = given_arr[i];
}
new_arr[i + 1] = '\0';
if ((i + 1 + 1) != (strLen + 1 + 1)) {
printf("WE GOT A MEMORY LEAK OUT THERE\n");
}
if (check != 0) {
free(given_arr);
}
return new_arr;
}
char* add_as_last(char *given_arr, char given_char, int check) {
int strLen = 0;
while (given_arr[strLen] != '\0') {
strLen++;
}
char* newString = (char*)malloc((strLen + 1 + 1) * sizeof(char));
int i = 0;
for(; i < strLen; i++) {
newString[i] = given_arr[i];
}
newString[i] = given_char;
newString[i + 1] = '\0';
if ((i + 1 + 1) != (strLen + 1 + 1)) {
printf("WE GOT A MEMORY LEAK OUT THERE\n");
}
return newString;
}
void forming_list(int file_arr[][y_size], int i, int j, char body[]) {
char thing = '0';
thing = j + '0';
body = add_as_first(body, thing, 1);
body = add_as_first(body, ',', 1);
thing = i + '0';
body = add_as_first(body, thing, 1);
body = add_as_first(body, ' ', 1);
if ((file_arr[i][j] == 1) || (file_arr[i][j] == 5)) {
if (j < x_size - 1) {
forming_list(file_arr, i, j + 1, body);
} else {
forming_list(file_arr, i + 1, 0, body);
}
} else if ((file_arr[i][j] == 2) || (file_arr[i][j] == 6)) {
if (j != 0) {
forming_list(file_arr, i, j - 1, body);
} else {
forming_list(file_arr, i - 1, x_size - 1, body);
}
} else if ((file_arr[i][j] == 3) || (file_arr[i][j] == 7)) {
if (i == 0) {
forming_list(file_arr, y_size - 1, j, body);
} else {
forming_list(file_arr, i - 1, j, body);
}
} else if ((file_arr[i][j] == 4) || (file_arr[i][j] == 8)) {
if (i == y_size - 1) {
forming_list(file_arr, 0, j, body);
} else {
forming_list(file_arr, i + 1, j, body);
}
}
}
void print_file(int file_arr[][y_size], char *res, char *body) {
int i = 0;
int j = 0;
for(i; i < y_size; i++) {
for (j; j < x_size; j++) {
if ((file_arr[i][j] >= 5) && (file_arr[i][j] <= 9)) {
res = add_as_last(res, '#', 1);
}
else if ((file_arr[i][j] >= 1) && (file_arr[i][j] <= 4)) {
res = add_as_last(res, '#', 1);
forming_list(file_arr, i, j, body);
} else {
res = add_as_last(res, 'x', 1);
}
}
res = add_as_last(res, '\n', 1);
printf("Length of string = %zu \n",strlen(res));
j = 0;
}
}
int main()
{
int disp[x_size][y_size] = {
{0, 1, 8, 0},
{0, 0, 8, 0},
{0, 9, 6, 0},
{0, 0, 0, 0}
};
char *res;
char *body;
res = (char*)malloc((1) * sizeof(char));
body = (char*)malloc((1) * sizeof(char));
res[0] = '\0';
body[0] = '\0';
printf("Length of string = %zu \n",strlen(res));
print_file(disp, res, body);
printf("Length of string = %zu \n",strlen(res));
printf("%s\n", res);
printf("%s\n", body);
return 0;
}
The output is:
Length of string = 0 //After creating a res line
Length of string = 5 //After the first outer for loop
Length of string = 10 //After the second outer for loop
Length of string = 15 //After the third outer for loop
Length of string = 20 //After the fourth outer for loop just before exiting function
Length of string = 0 //Outside the function before printing "res" string
//Printing empty "res" string
2,1 2,2 1,2 0,2 0,1 //Printing properly filled "body" string
Why "body" and "res" value is so different after my program is finished working, despite being so similar?
Your
print_file
function is modifyingres
, but the new pointer never gets passed back into main.So main has its
res
still pointing to the (long destroyed) originalres
, which produces undefined bahavior forstrlen
(or anything else).You should pass the
res
pointer by reference or pass the pointer to it, so the modification gets back into main.