as the title mention it : when passing a 3d array to a function, the memory address of the array suddenly change after performing an fget
the issue occurs in the insert function right after the fgets
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stddef.h> // for macro NULL
int clear_screen() {
int pid = fork();
if (pid == 0) {
char *newargv[] = { NULL };
char *newenviron[] = { "TERM=screen" };
execve("/usr/bin/clear", newargv, newenviron);
}
int wait_time = 1;
int *ptr_wait_time = &wait_time;
wait(ptr_wait_time);
return 0;
}
void init (char char_array[5][5][11]) {
printf("char_array in init is at %p which points to %p\n", &char_array, *char_array);
printf("char_array[0][0] in init is at %p\n", &char_array[0][0]);
printf("char_array[0][0][0] in init is at %p\n", &char_array[0][0][0]);
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
for (int single_char = 0; single_char < 11; single_char++) {
char_array[row][col][single_char] = ' ';
}
char_array[row][col][10] = '\0';
}
}
}
void display (char char_array[5][5][11]) {
printf("\t0\t\t\t\t1\t\t\t\t2\t\t\t\t3\t\t\t\t4\n");
for (int row = 0; row < 5; row++) {
printf("%d", row);
for (int col = 0; col < 5; col++) {
printf("\t%p[%s]", char_array[row][col], char_array[row][col]);
}
printf("\n");
}
}
int check_if_int (char *user_maybe_int) {
long result;
char *endptr;
result = strtol(user_maybe_int, &endptr, 10);
if (user_maybe_int[0] != '\n' && *endptr == '\n' && result > -1 && result < 5) {
return result;
}
else {
return -1;
}
}
char *format_user_input (char *user_input) {
int size_of_input;
int padding_size;
char *formated = malloc(11);
size_of_input = strcspn(user_input, "\n") - 1;
padding_size = 11 - size_of_input;
for (int i = 0; i < size_of_input + 1;i ++) {
formated[i] = user_input[i];
}
for (int i = size_of_input + 1; i < 11;i ++) {
formated[i] = ' ';
}
formated[10] = '\0';
return formated;
}
int insert (char char_array[5][5][11]) {
printf("char_array in insert is at %p which points to %p\n", &char_array, *char_array);
printf("char_array[0][0] in insert is at %p and points to %p\n", &char_array[0][0], char_array[0][0]);
printf("char_array[0][0][0] in insert is at %p\n", &char_array[0][0][0]);
char user_input_row[2];
char user_input_col[2];
printf("did char_array[0][0] changed1? %p points to %p (the answer is : not yet)\n", &char_array[0][0], char_array[0][0]);
int row;
printf("did char_array[0][0] changed2? %p points to %p (the answer is : not yet)\n", &char_array[0][0], char_array[0][0]);
int col;
printf("did char_array[0][0] changed3? %p points to %p (the answer is : not yet)\n", &char_array[0][0], char_array[0][0]);
char user_input[11] = "";
printf("did char_array[0][0] changed4? %p points to %p (the answer is : not yet)\n", &char_array[0][0], char_array[0][0]);
printf("insert in row : ");
printf("did char_array[0][0] changed5? %p points to %p (the answer is : not yet)\n", &char_array[0][0], char_array[0][0]);
fgets(user_input_row, 3, stdin);
printf("did char_array[0][0] changed6? %p points to %p (the answer is : yes, most of the time)\n", &char_array[0][0], char_array[0][0]);
row = check_if_int(user_input_row);
if (row == -1) {
return 1;
}
printf("insert in column : ");
fgets(user_input_col, 3, stdin);
col = check_if_int(user_input_col);
if (col == -1) {
return 1;
}
printf("your input : ");
fgets(user_input, 12, stdin);
char *user_input_formated = format_user_input(user_input);
//actual insert
printf("User try to insert at %p via char_array[%d][%d]\n", &char_array[row][col], row, col);
strncpy(char_array[row][col], user_input_formated, 11);
free(user_input_formated);
return 0;
}
void start (char char_array[5][5][11]) {
//clear_screen();
int insert_res;
// this function display a grid (memory address + content)
display(char_array);
insert_res = insert(char_array);
if (insert_res != 1) {
start(char_array);
}
else {
printf("something went wrong on insert!");
exit(1);
}
}
int main () {
// 3d array
// we define 5 x 5 array of arrays of chars (10 chars + null terminator)
// for a visual reprensentation, 2d arrays give columns, 3d arrays add rows
char char_array[5][5][11];
// this function fills each array of chars with "0000000000\0"
init(char_array);
// start the display/insert recursion
start(char_array);
}
as you can see from the multiples printf, I tried to pinpoint the exact moment where the memory address changed, from my understanding, char_array decays to a pointer when passed to this function and the memory address should not change (obviously, i'm missing something because it does change after performing the 1st fgets)
char_array in insert is at 0x7ffc4e60cd70 which points to 0x7ffc4e60cdb0
char_array[0][0] in insert is at 0x7ffc4e60cdb0 and points to 0x7ffc4e60cdb0
char_array[0][0][0] in insert is at 0x7ffc4e60cdb0
did char_array[0][0] changed1? 0x7ffc4e60cdb0 points to 0x7ffc4e60cdb0 (the answer is : not yet)
did char_array[0][0] changed2? 0x7ffc4e60cdb0 points to 0x7ffc4e60cdb0 (the answer is : not yet)
did char_array[0][0] changed3? 0x7ffc4e60cdb0 points to 0x7ffc4e60cdb0 (the answer is : not yet)
did char_array[0][0] changed4? 0x7ffc4e60cdb0 points to 0x7ffc4e60cdb0 (the answer is : not yet)
insert in row : did char_array[0][0] changed5? 0x7ffc4e60cdb0 points to 0x7ffc4e60cdb0 (the answer is : not yet)
0
did char_array[0][0] changed6? 0x7ffc4e60cd00 points to 0x7ffc4e60cd00 (the answer is : yes, most of the time)
did char_array[0][0] changed7? 0x7ffc4e60cd00 points to 0x7ffc4e60cd00 (the answer is : yes, most of the time)
insert in column : did char_array[0][0] changed8? 0x7ffc4e60cd00 points to 0x7ffc4e60cd00 (the answer is : yes, most of the time)
0
did char_array[0][0] changed9? 0x7ffc4e60cd00 points to 0x7ffc4e60cd00 (the answer is : yes, most of the time)
did char_array[0][0] changed10? 0x7ffc4e60cd00 points to 0x7ffc4e60cd00 (the answer is : yes, most of the time)
your input : a
did char_array[0][0] changed11? 0x7ffc4e60cd00 points to 0x7ffc4e60cd00 (the answer is : yes, most of the time)
User try to insert at 0x7ffc4e60cd00 via char_array[0][0]