I am trying to write a program simulating the matrix digital rain using curses.h
library and random numbers. The program seems to be working but the startup of the program is very slow (up to 10 seconds on MacOS 11.6.1, 2.8GHz Quad-Core Intel Core i7). Why is that? Is it relate to how random numbers are used? How can I improve the code so that the start of the program becomes snappy
Here is a snapshot of the usage of the program when I launch it:
PID COMMAND %CPU TIME #TH #WQ #PORTS MEM PURG CMPRS PGRP PPID STATE BOOSTS %CPU_ME %CPU_OTHRS UID FAULTS COW MSGSENT MSGRECV SYSBSD SYSMACH CSW PAGEINS IDLEW POWER INSTRS CYCLES USER #MREGS RPRVT VPRVT VSIZE KPRVT KSHRD
55710 matrix_digital_r 99.7 00:06.77 1/1 0 10 768K 0B 0B 55709 55709 running *0[1] 0.00000 0.00000 501 318 39 16 8 165 40 1333+ 0 0 99.7 12800790099 3889519761 user01 N/A N/A N/A N/A N/A N/A
after 10-20 second here is the same usage:
PID COMMAND %CPU TIME #TH #WQ #PORTS MEM PURG CMPRS PGRP PPID STATE BOOSTS %CPU_ME %CPU_OTHRS UID FAULTS COW MSGSENT MSGRECV SYSBSD SYSMACH CSW PAGEINS IDLEW POWER INSTRS CYCLES USER #MREGS RPRVT VPRVT VSIZE KPRVT KSHRD
65886 matrix_digital_r 0.4 00:36.54 1 0 10 632K 0B 0B 65846 65846 sleeping *0[1] 0.00000 0.00000 501 284 39 18 8 381+ 39 14329+ 0 19+ 0.5 8935555 8242181 user01 N/A N/A N/A N/A N/A N/A
(The PID are not the same because it was 2 different runs but, the result in one run is the same). One can notice the the numbers for %CPU
, INSTRS
and CYCLES
drastically decreases after a while and that the STATE
changes from running
to sleeping
Here is the code:
/*matrix_digital_rain.c*/
#include <curses.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "set_characters.h"
#include "hyperparameters.h"
#include "functions.h"
int main() {
srand((unsigned) time(NULL)); // Initialization, should only be called once.
setlocale(LC_ALL, "");
int max_y = 0, max_x = 0;
Drop_init_vals drop_init_vals01;
//Drop_init_vals drop_init_vals02;
//Drop_init_vals drop_init_vals03;
//Drop_init_vals drop_init_vals04;
//Drop_init_vals drop_init_vals05;
//Drop_init_vals drop_init_vals06;
//Drop_init_vals drop_init_vals07;
//Drop_init_vals drop_init_vals08;
//Drop_init_vals drop_init_vals09;
int iter_start01 = rand() % ITER_START_RANGE;
//int iter_start02 = rand() % ITER_START_RANGE;
//int iter_start03 = rand() % ITER_START_RANGE;
//int iter_start04 = rand() % ITER_START_RANGE;
//int iter_start05 = rand() % ITER_START_RANGE;
//int iter_start06 = rand() % ITER_START_RANGE;
//int iter_start07 = rand() % ITER_START_RANGE;
//int iter_start08 = rand() % ITER_START_RANGE;
//int iter_start09 = rand() % ITER_START_RANGE;
int iter = 0;
initscr();
noecho();
curs_set(FALSE);
start_color();
init_color(CUSTOM_GREEN1, 90, 280, 90);
init_color(CUSTOM_GREEN2, 100, 500, 100);
init_color(CUSTOM_GREEN3, 100, 900, 100);
init_color(COLOR_BLACK, 0, 0, 0);
char char_set[DIM_1_ARRAY_STRING][BYTES_PER_CHAR] = {SET_CHAR};
char str_display[DIM_0_ARRAY_STRING][DIM_1_ARRAY_STRING][BYTES_PER_CHAR];
for (int i = 0; i<DIM_0_ARRAY_STRING; i++){
//for (int j = 0; j<LEN_STRING_DISPLAY; j++){
for (int j = 0; j<DIM_1_ARRAY_STRING; j++){
strcpy(str_display[i][j], char_set[rand() % N_COMMAS]);
}
}
while(1)
{
getmaxyx(stdscr, max_y, max_x);
clear();
if (iter % ITER_REFRESH == iter_start01){
drop_init_vals01 = random_drop_init_vals(drop_init_vals01, iter);
drop_init_vals01.n_dim_str = 0;
}
print_n_string_from_string_array_struct(
drop_init_vals01,
str_display,
iter
);
/*
if (iter % ITER_REFRESH == iter_start02){
drop_init_vals02 = random_drop_init_vals(drop_init_vals02, iter);
drop_init_vals02.n_dim_str = 1;
}
print_n_string_from_string_array_struct(
drop_init_vals02,
str_display,
iter
);
if (iter % ITER_REFRESH == iter_start03){
drop_init_vals03 = random_drop_init_vals(drop_init_vals03, iter);
drop_init_vals03.n_dim_str = 2;
}
print_n_string_from_string_array_struct(
drop_init_vals03,
str_display,
iter
);
if (iter % ITER_REFRESH == iter_start04){
drop_init_vals04 = random_drop_init_vals(drop_init_vals04, iter);
drop_init_vals04.n_dim_str = 3;
}
print_n_string_from_string_array_struct(
drop_init_vals04,
str_display,
iter
);
if (iter % ITER_REFRESH == iter_start05){
drop_init_vals05 = random_drop_init_vals(drop_init_vals05, iter);
drop_init_vals05.n_dim_str = 4;
}
print_n_string_from_string_array_struct(
drop_init_vals05,
str_display,
iter
);
if (iter % ITER_REFRESH == iter_start06){
drop_init_vals06 = random_drop_init_vals(drop_init_vals06, iter);
drop_init_vals06.n_dim_str = 5;
}
print_n_string_from_string_array_struct(
drop_init_vals06,
str_display,
iter
);
if (iter % ITER_REFRESH == iter_start07){
drop_init_vals07 = random_drop_init_vals(drop_init_vals07, iter);
drop_init_vals07.n_dim_str = 6;
}
print_n_string_from_string_array_struct(
drop_init_vals07,
str_display,
iter
);
if (iter % ITER_REFRESH == iter_start08){
drop_init_vals08 = random_drop_init_vals(drop_init_vals08, iter);
drop_init_vals08.n_dim_str = 7;
}
print_n_string_from_string_array_struct(
drop_init_vals08,
str_display,
iter
);
if (iter % ITER_REFRESH == iter_start09){
drop_init_vals09 = random_drop_init_vals(drop_init_vals09, iter);
drop_init_vals09.n_dim_str = 8;
}
print_n_string_from_string_array_struct(
drop_init_vals09,
str_display,
iter
);
*/
iter++;
refresh();
usleep(DELAY);
}
attron(COLOR_PAIR(1));
attron(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
endwin();
refresh();
use_default_colors();
}
/*functions.c*/
#include "hyperparameters.h"
#include "functions.h"
#include <curses.h>
#include <time.h>
#include <stdlib.h>
void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(1, CUSTOM_GREEN1, COLOR_BLACK);
attron(COLOR_PAIR(1));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(2, CUSTOM_GREEN2, COLOR_BLACK);
attron(COLOR_PAIR(2));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(3, CUSTOM_GREEN3, COLOR_BLACK);
attron(COLOR_PAIR(3));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals, int iter)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
srand((unsigned int) (time_t)ts.tv_nsec);
drop_init_vals.y1 = 0;
drop_init_vals.x1 = rand() % X1_RANGE;
drop_init_vals.n_string = 5 + rand() % N_STRING_RANGE;
drop_init_vals.iter_init = iter;
return drop_init_vals;
}
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter)
{
int y1 = drop_init_vals.y1;
int x1 = drop_init_vals.x1;
int n_string = drop_init_vals.n_string;
int n_dim_str = drop_init_vals.n_dim_str;
int y_start = iter - drop_init_vals.iter_init;
int count = 0;
for (int i=y_start; i<y_start+n_string; i++)
{
if (count == 0 || count == 1){
print_GREEN1(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
else if (count == 2 || count == 3 || count == 4){
print_GREEN2(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
else{
print_GREEN3(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
count++;
}
}
//int gen_rand_int(){
// struct timespec ts;
// clock_gettime(CLOCK_MONOTONIC, &ts);
//
// srand((unsigned int) (time_t)ts.tv_nsec);
//
// return rand();
//}
/*functions.h*/
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
typedef struct {
int x1, y1, n_string, n_dim_str, iter_init;
} Drop_init_vals ;
int gen_rand_int(void);
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter);
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals, int iter);
void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
#endif
/*hyperparameters.h*/
#ifndef HYPERPARAMETERS_H
#define HYPERPARAMETERS_H
#define DELAY 60000 //480000
#define CUSTOM_GREEN1 8
#define CUSTOM_GREEN2 9
#define CUSTOM_GREEN3 10
#define COLOR_BLACK 0
#define DIM_0_ARRAY_STRING 20
#define DIM_1_ARRAY_STRING 100
#define BYTES_PER_CHAR 5
#define LEN_STRING_DISPLAY 100
#define MAX_Y 100
#define MAX_X 100
#define N_STRING_MAX 20
#define Y1_RANGE 10
#define X1_RANGE 30
#define N_STRING_RANGE 5
#define Y_START_RANGE 15
#define ITER_REFRESH 60
#define ITER_START_RANGE 25
#endif
/*set_characters.h*/
#ifndef SET_CHARACTERS_H
#define SET_CHARACTERS_H
#define N_COMMAS 56
#define SET_CHAR "ㇰ", "ㇱ", "ㇲ","ㇳ","ㇴ","ㇵ","ㇶ","ㇷ","ㇸ","ㇹ","ㇺ","ㇻ","ㇼ","ㇽ","ㇾ", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<", "=", ">", "T", "H","E", "M", "A", "T", "R", "I", "X", "Z", ":", "・", ".", "=", "*", "+", "-", "<", ">", "¦", "|", "#", "_"
#endif
#makefile
CC = gcc
CFLAGS = -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition
BINC=matrix_digital_rain
allc: $(BINC)
$(BINC): $(BINC).o functions.o
$(CC) $(CFLAGS) $(BINC).o functions.o -o $@ -lncurses
$(BINC).o: $(BINC).c set_characters.h hyperparameters.h set_characters.h
$(CC) $(CFLAGS) -c $(BINC).c
functions.o: functions.c functions.h
$(CC) $(CFLAGS) -c functions.c
clean:
$(RM) -rf $(BINC) *.dSYM *.o
runc: allc
./$(BINC)
EDIT
According to comments: I changed the code as follow:
DIM_2_ARRAY_STRING
in BYTES_PER_CHAR
in all the files and changed its value from 4 to 5DIM_1_ARRAY_STRING
from 200 to 100matrix_digital_rain.c
I changed the line for (int j = 0; j<LEN_STRING_DISPLAY; j++){
in for (int j = 0; j<DIM_1_ARRAY_STRING; j++){
makefile
I changed the line $(BINC): $(BINC).c $(BINC).o functions.o
to $(BINC): $(BINC).o functions.o
EDIT 2
So I followed the advices of John Bollinger and made an array of drop_init_vals
. This solved the problem of the slow startup (many thanks @JohnBollinger) and runs ok for low number of drops (#define N_DROPS
in hyperparameters.h
) but when there are many characters to be displayed on the screen, the characters are flickering and if I increase the number of drops to, let's say, 15, I get a segfault.
/*matrix_digital_rain.c*/
#include <curses.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "set_characters.h"
#include "hyperparameters.h"
#include "functions.h"
int main() {
srand((unsigned) time(NULL)); // Initialization, should only be called once.
setlocale(LC_ALL, "");
int max_y = 0, max_x = 0;
//Drop_init_vals drop_init_vals_array[N_DROPS] ;
Drop_init_vals drop_init_vals_array[N_DROPS] ;
//drop_init_vals_array[N_DROPS] = drop_init_vals_array_to_zero(&drop_init_vals_array[N_DROPS]);
for (int drop_num = 0; drop_num < N_DROPS; drop_num++){
drop_init_vals_array[drop_num] = drop_init_vals_array_to_zero(drop_init_vals_array[drop_num]);
drop_init_vals_array[drop_num].rand_iter_start = rand() % ITER_START_RANGE;
}
int iter = 0;
initscr();
noecho();
curs_set(FALSE);
start_color();
init_color(CUSTOM_GREEN1, 90, 280, 90);
init_color(CUSTOM_GREEN2, 100, 500, 100);
init_color(CUSTOM_GREEN3, 100, 900, 100);
init_color(COLOR_BLACK, 0, 0, 0);
char char_set[DIM_1_ARRAY_STRING][BYTES_PER_CHAR] = {SET_CHAR};
char str_display[DIM_0_ARRAY_STRING][DIM_1_ARRAY_STRING][BYTES_PER_CHAR];
for (int i = 0; i<DIM_0_ARRAY_STRING; i++){
for (int j = 0; j<DIM_1_ARRAY_STRING; j++){
strcpy(str_display[i][j], char_set[rand() % N_COMMAS]);
}
}
while(1)
{
getmaxyx(stdscr, max_y, max_x);
clear();
for (int drop_num = 0; drop_num<N_DROPS; drop_num++){
if (iter % ITER_REFRESH == drop_init_vals_array[drop_num].rand_iter_start){
//drop_init_vals_array[drop_num] = random_drop_init_vals(drop_init_vals_array[drop_num], iter);
drop_init_vals_array[drop_num].n_dim_str = drop_num;
drop_init_vals_array[drop_num].x1 = rand() % X1_RANGE;
drop_init_vals_array[drop_num].n_string = 20 + rand() % N_STRING_RANGE;
drop_init_vals_array[drop_num].iter_init = iter;
drop_init_vals_array[drop_num].rand_iter_start_bool = 1;
}
if(drop_init_vals_array[drop_num].rand_iter_start_bool == 1){
print_n_string_from_string_array_struct(
drop_init_vals_array[drop_num],
str_display,
iter
);
//if (drop_init_vals_array[drop_num].iter_init == ITER_REFRESH){
if (iter == drop_init_vals_array[drop_num].iter_init + ITER_REFRESH){
drop_init_vals_array[drop_num].rand_iter_start_bool = 0;
}
}
}
iter++;
refresh();
usleep(DELAY);
}
attron(COLOR_PAIR(1));
attron(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
endwin();
refresh();
use_default_colors();
}
/*functions.c*/
#include "hyperparameters.h"
#include "functions.h"
#include <curses.h>
#include <time.h>
#include <stdlib.h>
void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(1, CUSTOM_GREEN1, COLOR_BLACK);
attron(COLOR_PAIR(1));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(2, CUSTOM_GREEN2, COLOR_BLACK);
attron(COLOR_PAIR(2));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
init_pair(3, CUSTOM_GREEN3, COLOR_BLACK);
attron(COLOR_PAIR(3));
mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}
Drop_init_vals drop_init_vals_to_zero(void)
{
Drop_init_vals drop_init_vals;
drop_init_vals.y1 = 0;
drop_init_vals.x1 = 0;
drop_init_vals.n_string = 0;
drop_init_vals.iter_init = 0;
drop_init_vals.n_dim_str = 0;
return drop_init_vals;
}
//Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals, int iter)
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals)
{
//drop_init_vals.y1 = 0;
drop_init_vals.x1 = rand() % X1_RANGE;
drop_init_vals.n_string = 20 + rand() % N_STRING_RANGE;
//drop_init_vals.iter_init = iter;
return drop_init_vals;
}
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter)
{
int y1 = drop_init_vals.y1;
int x1 = drop_init_vals.x1;
int n_string = drop_init_vals.n_string;
int n_dim_str = drop_init_vals.n_dim_str;
int y_start = iter - drop_init_vals.iter_init;
int count = 0;
for (int i=y_start; i<y_start+n_string; i++)
{
if (count == 0 || count == 1){
print_GREEN1(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
else if (count == 2 || count == 3 || count == 4){
print_GREEN2(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
else{
print_GREEN3(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
}
count++;
}
}
//int gen_rand_int(){
// struct timespec ts;
// clock_gettime(CLOCK_MONOTONIC, &ts);
//
// srand((unsigned int) (time_t)ts.tv_nsec);
//
// return rand();
//}
Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals)
{
for (int drop_num = 0; drop_num < N_DROPS; drop_num++){
//Drop_init_vals drop_init_vals;
drop_init_vals.y1 = 0;
drop_init_vals.x1 = 0;
drop_init_vals.n_string = 0;
drop_init_vals.iter_init = 0;
drop_init_vals.n_dim_str = 0;
}
return drop_init_vals;
}
/*functions.h*/
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
typedef struct {
int x1, y1, n_string, n_dim_str, iter_init, rand_iter_start, rand_iter_start_bool;
} Drop_init_vals ;
int gen_rand_int(void);
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter);
//Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals, int iter);
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals);
Drop_init_vals drop_init_vals_to_zero(void);
void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
//Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals_array[N_DROPS]);
Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals);
#endif
/*set_characters.h*/
#ifndef SET_CHARACTERS_H
#define SET_CHARACTERS_H
#define N_COMMAS 56
#define SET_CHAR "ㇰ", "ㇱ", "ㇲ","ㇳ","ㇴ","ㇵ","ㇶ","ㇷ","ㇸ","ㇹ","ㇺ","ㇻ","ㇼ","ㇽ","ㇾ", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<", "=", ">", "T", "H","E", "M", "A", "T", "R", "I", "X", "Z", ":", "・", ".", "=", "*", "+", "-", "<", ">", "¦", "|", "#", "_"
#endif
/*hyperparameters.h*/
#ifndef HYPERPARAMETERS_H
#define HYPERPARAMETERS_H
#define DELAY 60000 //480000
#define CUSTOM_GREEN1 8
#define CUSTOM_GREEN2 9
#define CUSTOM_GREEN3 10
#define COLOR_BLACK 0
#define DIM_0_ARRAY_STRING 20
#define DIM_1_ARRAY_STRING 100
#define BYTES_PER_CHAR 5
#define LEN_STRING_DISPLAY 100
#define MAX_Y 100
#define MAX_X 100
#define N_STRING_MAX 20
#define N_DROPS 16
#define Y1_RANGE 20
#define X1_RANGE 30
#define N_STRING_RANGE 5
#define Y_START_RANGE 15
#define ITER_REFRESH 80
#define ITER_START_RANGE 80
#endif
#makefile
CC = gcc
CFLAGS = -O2 -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition
BINC=matrix_digital_rain
allc: $(BINC)
$(BINC): $(BINC).o functions.o
$(CC) $(CFLAGS) -ggdb3 $(BINC).o functions.o -o $@ -lncurses
$(BINC).o: $(BINC).c set_characters.h hyperparameters.h set_characters.h
$(CC) $(CFLAGS) -c $(BINC).c
functions.o: functions.c functions.h
$(CC) $(CFLAGS) -c functions.c
clean:
$(RM) -rf $(BINC) *.dSYM *.o
runc: allc
./$(BINC)
The main problem appears to be that you are using drop_init_vals01
- drop_init_vals09
uninitialized. Consider this ...
int iter = 0; // ... while (1) { // ... if (iter % ITER_REFRESH == iter_start09){ drop_init_vals09 = random_drop_init_vals(drop_init_vals09, iter); drop_init_vals09.n_dim_str = 8; } print_n_string_from_string_array_struct( drop_init_vals09, str_display, iter ); // ... iter++; // ... }
Remembering that none of the drop_init_valsXX
have been initialized before loop entry, observe that drop_init_vals09
is passed to print_n_string_from_string_array_struct()
on every iteration of the loop, but only when the value of iter
reaches iter_start09
is drop_init_vals09
filled in. The same applies to all the other drop_init_valsXX
variables, including drop_init_vals01
. The program exhibits undefined behavior as a result.
I'm not sure why the manifestation of that UB is so different when you use nine variables than when you use only one, but "undefined" means what it says.
Additional notes:
The reason for the issue became clear to me after I identified the nature of the issue by running the program under Valgrind.
The program is begging for (more) use of arrays. Note all the code duplication in matrix_digital_rain.c
. That source could be shrunk to less than half its current size while at the same time being made more flexible and robust by using an array of Drop_init_vals
objects instead nine separate variables of that type (in conjunction with also using an array of int
instead of nine separate int
variables for the iter_start_vals
). You then have an inner loop over those inside your while
loop instead of separate code for each one.