WIP version of ex1-17-2.c that crashes during a memory safety check in store() for some reason. If I comment out the check, it spins and segfaults. Cause unknown.

This commit is contained in:
Reina Harrington-Affine 2025-09-16 18:54:10 +00:00
parent df60eb6528
commit 2084b2ae84

94
KNR C/ex1-17-2.c Normal file
View file

@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
// Initialize array for bulk storage of incoming text. . .
char buffer[32000] = {0};
char output[64000] = {0};
//Global information about the state of output[] to circumvent costly seeking
//of double null by loop.
int outputCrsr = 0;
int* locOutCrsr = &outputCrsr;
// Function for storing from the input buffer to array
void store(char storage[]);
// Function for sorting through data in buffer[]
void enumerate(char data[]);
// Function for recalling and printing data identified for recall by enumerate()
void recall(char from[]);
// Function to copy from one array to another
void replicate(char from[], char to[]);
int main(){
store(buffer); // Calls store() to write from stdin to storage
enumerate(buffer);// Calls enumerate() to seek and enumerate lines of
// length 80 or greater.
recall (output); //calls recall() to print output[] to stdout
return 0;
}
// Important to note that store intentionally does not print EOF to the storage
void store(char storage[]){
int cursor = 0;
int lim = 32000; //TODO Un-hardcode this. Using strlen resulted in a spin
//due to interactions with a memory safety check in a
//previous version.
for(int current = getchar(); current != EOF; ++cursor){
// Begin memory safety check. . .
if (cursor >= (lim - 1)){
printf("%s", "Error: Input exceeds size of storage (32kB).");
exit(EXIT_FAILURE);
}
storage[cursor] = current;
}
}
// Enumerate breaks on first encountered null character (i.e. end of used space
//in data[]
void enumerate(char data[]){
int curLineLen = 0; // Current line length (characters since last newline)
int dataCursor = 0; // Currently accessed position in data[]
char workingStorage[32000]; // Local storage for enumerate while working
int wSCursor = 0; // Currently accessed position in workingStorage[]
for(int current = data[dataCursor]; current != '\0'; ++dataCursor){
if(current != '\n'){
workingStorage[wSCursor] = current;
++curLineLen;
} else if (current == '\n' && curLineLen >= 80){
workingStorage[wSCursor] = current;
++wSCursor;
workingStorage[wSCursor] = '\0';
replicate(workingStorage, output);
} else if (current == '\n' && curLineLen < 80){
wSCursor = 0;
}
}
}
//TODO Shift internal cursor to first double null in output[], increment cursor,
//and write new data to output[]. Break on first encountered input null.
void replicate(char from[], char to[]){
//TODO Malloc a variable inside replicate() to replace outputCrsr and locOutCrsr
//because the fact that replicate() depends on global variables like that is a
//readability nightmare. This is the only fucntion that depends on them.
int toCrsr = 0;
int fromCrsr = 0;
int last = 0;
toCrsr = outputCrsr; //Shift toCrsr to the last written position in output.
++toCrsr; //Step forward 1 byte in to[] in order to preserve a null space
for(int current = from[fromCrsr]; current != '\0'; ++fromCrsr){
to[toCrsr] = from[fromCrsr];
++toCrsr;
}
*locOutCrsr = toCrsr; //Set global state of output.
}
void recall(char from[]){
printf("%s", from);
}