Randomly Pair Teams From Text File Twice [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm fairly new to C programming and I'm attempting to complete this random pairing program but I'm having issues with starting it. Basically, the program needs to read in the 3 letter team names from a text file, place them into an array, and then randomly pair teams against each other. There are two rounds and in the second round, there cannot be any rematches. Additionally, teams from the same school cannot play against each other. Teams from the same school share the same first character and line in the text file. Can anyone help me with how to code this? :) Here is the text file named provisions.txt:
ABA ABC ABD ABG
BAA BAB BAC
CAB CBA
DAB DBC DBE DBA
EAB
FAB FAC FAA
GAB GAA
HAA HAB
IAB
JAA
KAA
LAL LAB
MAA MAB MBA MUM
NAN NAB
My code so far is:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main()
{
// Read characters from text file into array
FILE *file = fopen("provision.txt", "r");
char teamList[115];
char teams[32][4]; // Holds team names
int i;
for(i = 0; i < 32; i++){
fscanf(file, "%s", teams[i]);
}
for(i = 0; i < 32; i++){
printf("%s \n", teams[i]); // Test to make sure teams are read in
}
// Clean up
fclose(file);
return 0;
}
If possible, I would like to store the output of both rounds in text files named round1_pairings.txt and round2_pairings.txt.

This program attempts to solve a few subtle problems such as random selection bias, backing out of dead-end matching attempts, etc. It is not guaranteed to terminate in the case where a given round cannot be paired due to insufficient teams from other schools, which is more likely to occur at higher numbers of rounds (unlikely with only two rounds and many schools).
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NAMELEN 3
#define ROUNDS 2
#define RETRIES 10 // max attempts before restarting matching
#define STR_HELPER(x) #x // http://stackoverflow.com/a/5459929/4323
#define STR(x) STR_HELPER(x)
#define NAMEPRINTF "%" STR(NAMELEN) "s"
typedef char team_t[NAMELEN + 1];
typedef struct
{
team_t team;
team_t opponents[ROUNDS];
} pairing_t;
// the first round is round=0
// when round>0, prior round matches will be prevented from recurring
void make_matches(pairing_t* pairings, size_t count, size_t round)
{
// clip random() range to avoid bias toward first teams
long randmax = LONG_MAX - LONG_MAX % count - 1;
begin:
for(size_t ii = 0; ii < count; ++ii) {
if(pairings[ii].opponents[round][0]) continue; // already paired
//printf("matching: %s\n", pairings[ii].team);
unsigned retry = 0;
while(retry < RETRIES) {
long rand = random();
if (rand > randmax) continue; // avoid bias
pairing_t *opp = &pairings[rand % count];
if(opp->team[0] == pairings[ii].team[0]) { // same school
++retry;
continue;
}
if(opp->opponents[round][0]) continue; // already paired
size_t prior;
for(prior = 0; prior < round; ++prior) {
if(!memcmp(opp->team, pairings[ii].opponents[prior], sizeof(team_t))) {
break;
}
}
if(prior != round) continue; // duplicate pairing
//printf("match made: %s %s\n", opp->team, pairings[ii].team);
memcpy(pairings[ii].opponents[round], opp->team, sizeof(team_t));
memcpy(opp->opponents[round], pairings[ii].team, sizeof(team_t));
break;
}
if(retry == RETRIES) { // matching failed, start again
for(size_t ii = 0; ii < count; ++ii) {
memset(pairings[ii].opponents[round], 0, sizeof(team_t));
}
goto begin;
}
}
}
int main(void)
{
srandom(time(NULL));
FILE *file = fopen("provision.txt", "r");
size_t capacity = 15; // arbitrary initial size
pairing_t *pairings = calloc(capacity, sizeof(pairing_t));
if(!pairings) abort();
size_t count = 0;
while(fscanf(file, NAMEPRINTF, pairings[count].team) != EOF) {
//printf("%s\n", pairings[count].team);
++count;
if(count >= capacity) { // expand array
capacity *= 2;
pairings = realloc(pairings, capacity * sizeof(pairing_t));
if(!pairings) abort();
memset(&pairings[count], 0, (capacity - count) * sizeof(pairing_t));
}
}
for(size_t round = 0; round < ROUNDS; ++round) {
make_matches(pairings, count, round);
}
for(size_t ii = 0; ii < count; ++ii) {
printf("%s %s %s\n", pairings[ii].team, pairings[ii].opponents[0], pairings[ii].opponents[1]);
}
free(pairings);
fclose(file);
return 0;
}
The output is a simple table with three columns: the team playing, their first opponent, and their second opponent. I'm sure you can figure out how to write these to separate files as required.

Related

How do I assign an array of structs using for loop to be printed out?

I am new to coding and still learning, so I would like to thank you for all the feed back that you give, Thank you.
Currently I have a code that is able to read in all the names of the customers that are stored in the file. However it is not able to read in all the produce items and their amount other then the first three.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
#define STRSIZE 31
#define INVENSIZE 31
typedef struct{
char fname[STRSIZE];
char lname[STRSIZE];
} fullname;
typedef struct{
int count;
char pname[STRSIZE];
} koala;
typedef struct{
koala order[INVENSIZE];
fullname comname[STRSIZE];
} consumers;
void ReadInCustomer (consumers *c){
//reading in file and cheking if it exist
FILE * CinFile;
if ((CinFile =fopen("customers.txt","r")) == NULL){
printf("ERROR: WRONG FILE");
}
else{
//printf("I was able to read in customer file!!\n");
}
//assigning file elements into struct
int i;
int j;
for(i =0; i < 12; i++){
fscanf(CinFile,"%s %s", c->comname[i].fname, c->comname[i].lname);
for (j=0; j < 3; j++){
fscanf(CinFile, "%s %d", c->order[j].pname, &c->order[j].count);
}
}
fclose(CinFile);
}
int main(){
consumers con;
ReadInCustomer (&con);
int i;
int j;
for(i =0; i < 12; i++){
printf("%s %s\n", con.comname[i].fname, con.comname[i].lname);
for (j=0; j < 3; j++){
printf(" %11s: %d\n", con.order[j].pname, con.order[j].count);
}
}//printing out all of the customer and their orders
}
the file that I am reading in looks like this where it is for now repeated 12 times. where each element is all different. The sample below is just for example.
Firstname1 lastname1
item1 001
item2 010
item3 100
Firstname2 lastname2
item4 001
item5 010
item6 100
...
If you expect to be able to store multiple koalas per consumers, this will not do it. How this would typically be accomplished in this context would be to declare the structure like this:
#include <stdio.h>
#include <stdlib.h>
#define MAX_CONSUMERS 10
#define STRSIZE 31
#define INVENSIZE 31
typedef struct{
char fname[STRSIZE];
char lname[STRSIZE];
} fullname;
typedef struct{
int count;
char pname[STRSIZE];
} koala;
typedef struct{
koala order[INVENSIZE];
fullname comname;
} consumer;
void ReadInCustomer (consumer *c)
{
// Opening in-file and reading it
const char *inFile = "customers.txt";
FILE *inFp = fopen(inFile, "r");
if (!inFp) {
perror(inFile);
exit(1);
}
// else printf("I was able to open the customer file!!\n");
// assigning file elements into struct
for (int i = 0; i < 12; i++) {
fscanf(inFp,"%s %s", c[i].comname.fname, c[i].comname.lname);
for (int j = 0; j < 3; j++) {
fscanf(inFp, "%s %d", c[i].order[j].pname, &c[i].order[j].count);
}
}
fclose(inFp);
}
int main(void) {
consumer con[MAX_CONSUMERS];
ReadInCustomer(con);
for (int i = 0; i < 12; i++) {
printf("%s %s\n", con[i].comname.fname, con[i].comname.lname);
for (int j = 0; j < 3; j++)
printf(" %11s: %d\n", con[i].order[j].pname, con[i].order[j].count);
}//printing out all of the customers and their orders
}
Your program is writing to only the first 3 index of array koala order[INVENSIZE]; of structure consumers. The value you get for count and pname will be the last read values. Check this part of code of ReadInCustomer() function:
.....
for (j=0; j < 3; j++){
fscanf(CinFile, "%s %d", c->order[j].pname, &c->order[j].count);
.....
For every customer, the items read are stored in first 3 indexes of order array member of structure consumers.
The way you have defined the consumers structure, using j as index will not work. Instead of using value of j as index, you should use (i * 3) + j as index while filling order array because every consumer has 3 items listed under their name in the file. It should be:
.....
for (j=0; j < 3; j++){
fscanf(CinFile, "%s %d", c->order[(i * 3) + j].pname, &c->order[(i * 3) + j].count);
.....
Similar changes while printing the values (in main()):
.....
for (j=0; j < 3; j++){
printf(" %11s: %d\n", con.order[(i * 3) + j].pname, con.order[(i * 3) + j].count);
.....
Another minor problem in your code is - if due to some reason, fopen fails, your program will print a message to console and then attempt to read a NULL pointer. You should return in case of fopen() failure :
if ((CinFile =fopen("customers.txt","r")) == NULL){
printf("ERROR: WRONG FILE");
return; // This is missing in your code
}
With this also, there would be a problem - the main() function which is calling ReadInCustomer() function will not come to know whether the reading of file was successful or any error occurred. Irrespective of whether file read successfully or not, the main() function will attempt to print the values of consumers structure members.
It would be better to change the return type of ReadInCustomer() function from void to int and return, say, -1 in case of failure. Check this return value of ReadInCustomer() function in the calling function and based on this return value take the next decision.

Boyer Moore replace more than one pattern

I am working on a string search and replace project. I can only change 1 of the target pattern in the sentence. But I can find both.
Example: just do it. you will do it.
find: do
replace: think
expected---> just think it. you will think it.
what actually happened ---> just do it. you will think it.
How can I replace both of them?
I read the sentence from file input.txt
# include <limits.h>
# include <string.h>
# include <stdio.h>
#include <sys/time.h>
# define NO_OF_CHARS 256
# define MAX 10000
int sum = 0;
int control = 0;
// A utility function to get maximum of two integers
int max (int a, int b) { return (a > b)? a: b; }
// The preprocessing function for Boyer Moore's bad character heuristic
void badCharHeuristic( char *str, int size, int badchar[NO_OF_CHARS]) {
int i;
// Initialize all occurrences as -1
for (i = 0; i < NO_OF_CHARS; i++)
badchar[i] = -1;
// Fill the actual value of last occurrence of a character
for (i = 0; i < size; i++)
badchar[(int) str[i]] = i;
}
/* A pattern searching function that uses Bad Character Heuristic of Boyer Moore Algorithm */
void search( char *txt, char *pat,char temp3[MAX],int k,char*r) {
int m = strlen(pat);
int n = strlen(txt);
char src[MAX],p[MAX],temp[MAX],temp2[MAX],tempP[MAX],out[MAX];
int badchar[NO_OF_CHARS],i,leng,l,count;
char v;
/* Fill the bad character array by calling the preprocessing function badCharHeuristic() for given pattern */
badCharHeuristic(pat, m, badchar);
leng = strlen(pat);
strcpy(tempP,r);
//strcat(tempP,"</mark>");
leng = strlen(pat);
l = strlen(txt);
int s = 0; // s is shift of the pattern with respect to text
while(s <= (n - m)) {
int j = m-1;
/* Keep reducing index j of pattern while characters of pattern and text are matching at this shift s */
while(j >= 0 && pat[j] == txt[s+j]) {
count++;
j--;
}
/* If the pattern is present at current shift, then index j will become -1 after the above loop */
if (j < 0) {
//printf("pattern occurs at shift = %d\n", s);
/* Shift the pattern so that the next character in text
aligns with the last occurrence of it in pattern.
The condition s+m < n is necessary for the case when
pattern occurs at the end of text */
printf("The desired pattern was found starting from %d. line at position %d\n",k,s+1);
strncpy(temp, txt, s);
temp[s] = '\0';
//strcat(temp,"<mark>");
control++;
strcat(temp,tempP);
for(i=0;i<MAX;i++) {
if((s+leng+i)<strlen(txt))
temp2[i] = txt[s+leng+i];
else
temp2[i] = v;
}
strcat(temp,temp2);
strcpy(temp3,temp);
s += (s+m < n)? m-badchar[txt[s+m]] : 1;
}
else
/* Shift the pattern so that the bad character in text
aligns with the last occurrence of it in pattern. The
max function is used to make sure that we get a positive
shift. We may get a negative shift if the last occurrence
of bad character in pattern is on the right side of the
current character. */
s += max(1, j - badchar[txt[s+j]]);
}
sum +=count;
}
/* Driver program to test above funtion */
int main() {
char txt[MAX],p[MAX],r[MAX],temp[MAX],temp2[MAX],tempP[MAX],out[MAX];
int k = 1;
FILE *input = fopen("input.txt","r");
FILE *output = fopen("output.txt","w");
printf("Enter the text in which pattern is to be searched:");
fgets(p, MAX, stdin);
printf("Enter the text in which pattern is to be replaced:");
fgets(r, MAX, stdin);
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
p[strlen(p)-1]='\0';
temp[1]='a';
while(!feof(input)){
if(fgets (txt, MAX, input)!=NULL) {
txt[strlen(txt)-1] = '\0';
search(txt, p,temp,k,r);
if(temp[1]!='a') {
fprintf(output,"%s\n",temp);
temp[1]='a';
}
else
fprintf(output,"%s\n",txt);
}
k++;
}
if(control==0) {
printf("\nThe pattern was not found in the given text\n\n");
}
gettimeofday(&tv2, NULL);
printf ("Total time = %f seconds\n", (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec));
fclose(input);
fclose(output);
printf("The number of character comparison: %d\n",sum);
return 0;
}

Add Two numbers present in two files and write it another file. numbers are too large not fit in integer bounds [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 days ago.
Improve this question
It's an interview question asked in amazon.
Given two very large numbers i.e., they dnt fit in integer bounds of 'C' lang, in two different files. tell me the sum of both the numbers.
Here's one way to do it, which could be modified to read strings of digits from two files, instead of from standard input via scanf. This will read strings of digits up to MAX_LEN in length.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 10000
int main(int argc, char **argv)
{
/* read in first string */
char *fs = NULL;
fs = malloc(MAX_LEN);
if (!scanf("%s", fs)) {
fprintf(stderr, "Error: Could not read first string!\n");
return EXIT_FAILURE;
}
size_t fs_len = strlen(fs);
/* populate result array with first string digits */
short *res = NULL;
int res_len = MAX_LEN + 1;
res = malloc(sizeof(short) * res_len);
for (int res_idx = res_len - 1; res_idx >= 0; res_idx--) {
if (res_idx > (fs_len - 1)) {
res[res_idx] = 0;
continue;
}
int digit = fs[fs_len - res_idx - 1] - (int)'0';
res[res_idx] = digit;
/* error checking */
if ((res[res_idx] < 0) || (res[res_idx] > 9)) {
fprintf(stderr, "Error: Bad digit in fs at index %lu\n", fs_len - res_idx - 1);
return EXIT_FAILURE;
}
}
free(fs), fs = NULL;
/* read in first string */
char *ss = NULL;
ss = malloc(MAX_LEN);
if (!scanf("%s", ss)) {
fprintf(stderr, "Error: Could not read second string!\n");
return EXIT_FAILURE;
}
size_t ss_len = strlen(ss);
/* do the summation */
for (int ss_idx = ss_len - 1, res_idx = 0; ss_idx >= 0; ss_idx--, res_idx++) {
int digit = ss[ss_idx] - (int)'0';
/* error checking */
if ((digit < 0) || (digit > 9)) {
fprintf(stderr, "Error: Bad digit in ss at index %d\n", ss_idx);
return EXIT_FAILURE;
}
int temp_res = res[res_idx] + digit;
/* do we need to carry up? */
if (temp_res >= 10) {
res[res_idx + 1] += 1;
res[res_idx] = temp_res - 10;
}
else {
res[res_idx] = temp_res;
}
}
free(ss), ss = NULL;
/* print result */
for (int res_idx = (fs_len > ss_len ? fs_len : ss_len); res_idx >= 0; res_idx--) {
fprintf(stdout, "%d", res[res_idx]);
}
fprintf(stdout, "\n");
free(res), res = NULL;
return EXIT_SUCCESS;
}
It only keeps two arrays in memory at most, one char array and one short array. A char array would hold MAX_LEN bytes, and the short array would hold (MAX_LEN + 1) * 2 bytes, on systems where a short is two bytes.
If you read one character at a time from the two files, with the FILE pointer reading from the end of the file to the start, you could reduce this to just an array of short.
For further optimization, if you can bear the expense of two passes over the files (which might not be too expensive, given file caching), you could do a first pass on both strings to get their lengths. Given the larger of the two lengths, you can then allocate only as many short as you need to perform the summation, which would be the larger of the two lengths, plus one. Another option is to realloc your short array as you go along.

C - Perceptron school project - single data set, error not converging

Hello everyone,
I'm currently stuck working on a school project described as such:
Your program should read in the file in.csv, and adjust the weights of the perceptron so that when given the inputs it was trained with, it provides the corresponding outputs.
In reality, the error may never get to zero when training an ANN; the goal is to hopefully make it smart enough to recognize most instances. For this project start with an error of 5%, or 0.05. This would mean, for example, that the ANN correctly identified 95/100 of the inputs, and 05/100 were mistakenly classified. See if you can modify the parameters of the ANN training process to do better than 5%, but your program should not continue trying to modify the weights after 500,000 iterations.
Sample run: C:\percy in.csv 100 5 10
where the executable is percy.exe, the input file is in.csv, the learning rate is 100/1000=0.100, the error is 5/100, and max iterations is in thousands, so 10 corresponds to 10,000.
The input file is formatted per the example below. The first 16 characters in line represent sensor inputs, and the last char is always either 0 or 1, and represents which class the input corresponds to.
0000000001000000,0
0000000001000001,1
0000000001000010,1
0000000001000011,1
0000000001000100,1
these few numbers are a portion of the data set being used, the rest of the data set are similar integers
So the output is supposed to look like so:
iterationError = 0.023437500, errCnt = 3, repNum=72
wt[00]: +0.00661 wt[01]: +0.00431 wt[02]: +0.00011 wt[03]: +0.00814
wt[04]: +0.00198 wt[05]: +0.00470 wt[06]: +0.00356 wt[07]: +0.00435
wt[08]: +0.00761 wt[09]: +0.52254 wt[10]: +0.00120 wt[11]: -0.01169
wt[12]: -0.00937 wt[13]: -0.00281 wt[14]: -0.00157 wt[15]: -0.00217
STOP*****(with setting wt[10] to 0.5232)
However, when I run my code (below) with reading in the .csv data set, the program runs until it hits 10k iterations and the error doesn't change and I'm not exactly sure what may be wrong with my loop or calculations. Also I should note that my current code doesn't represent the correct output yet.
Any help would be greatly appreciated, thank you
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define LEARNING_RATE 0.1
#define MAX_ITERATION 10000
float randomFloat()
{
return (float)rand() / (float)RAND_MAX;
}
int calculateOutput(float weights[], int x)
{
float sum = x * weights[0] + weights[1];
return (sum >= 0) ? 1 : -1;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
float weights[2], localError, globalError, MAX_ERROR = 0.05;
float x[208];
int outputs[208], patternCount, i, p, iteration, output;
FILE *fp;
if ((fp = fopen("in.csv", "r")) == NULL) {
printf("Cannot open file.\n");
exit(1);
}
i = 0;
while (fscanf(fp, "%f,%d", &x[i], &outputs[i]) != EOF) {
i++;
}
patternCount = i;
weights[0] = randomFloat();
weights[1] = randomFloat();
iteration = 0;
do {
printf(" Iteration: %d ***********************************\n", iteration);
iteration++;
globalError = 0;
for (p = 0; p < patternCount; p++) {
output = calculateOutput(weights, x[p]);
localError = outputs[p] - output;
weights[0] += LEARNING_RATE * localError * x[p];
weights[1] += LEARNING_RATE * localError;
globalError += (localError*localError);
printf("%.1f \n", weights[0]);
}
globalError = globalError/((float)patternCount);
printf(" iterationError = %.5f\n", globalError);
} while ((globalError > MAX_ERROR) && (i < MAX_ITERATION));
return 0;
}

Pi spigot, implemented in C, segfaults when number of digits is too high [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I have made an implementation of a spigot algorithm in C, however, it segfaults (SIGSEGV) when the number of decimals to calculate is too high. The number of digits the error occurs at is slightly different on a few different windows computers I have, but it happens around 156210. I would give only the relevant code, but I honestly don't really understand the error, so I will give you my full code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int held[20]; //I wont have 19 consecutive 9's in pi, right?
int held_length = sizeof(held)/sizeof(int);
FILE *f;
void releaseDigits() {
int c;
for(c = held_length-1; c >= 0; c--) {
if(held[c] != -1) {
//printf("release: %i\n", held[c]); //debugging output
fprintf(f, "%i", held[c]);
}
}
}
void incHeld() {
int c;
for(c = held_length-1; c >= 0; c--) {
if(held[c] != -1) {
held[c]++;
}
}
}
void blankHeld() {
int c;
for(c = held_length-1; c >= 0; c--) {
held[c] = -1;
}
/*for(c = 0; c < held_length; c++) {
printf("BLANK_%i:%i\n", c, held[c]);
}*/ //debugging output
}
void deleteLast() {
int c = held_length-1;
while(held[c] != -1) {
c--;
}
held[c+1] = -1;
}
void holdDigit(int hold) {
int c = held_length-1;
while(held[c] != -1) {
c--;
}
held[c] = hold;
for(c = 0; c < held_length; c++) {
//printf("held_%i:%i\n", c, held[c]); //debugging output
}
}
void main() {
time_t start, end;
int n; //decimals of pi, 156207 max if printf, 156210 if fprintf, higher = sivsegv
printf("Decimal places of pi to calculate (max 156210 for now): ");
scanf("%i", &n);
start = clock();
f = fopen("pi.txt", "w"); //open file
if (f == NULL) {
printf("Error opening file!\n");
exit(1);
}
n++; //overcompensate for odd ending digit error
//initial array of 2,2,2,...2
int rem[((10*n)/3)+2]; //sizeof(one)/sizeof(int);
int init_count;
for(init_count = 0; init_count < ((10*n)/3)+2; init_count++) {
rem[init_count] = 2;
}
//main digit loop
int carry;
int decimal;
int pi_digit;
for(decimal = 0; decimal <= n; decimal++) {
carry = 0;
int sum;
int i;
for(i = (10*n)/3 + 1; i >= 1; i--) {
sum = (rem[i]*10)+carry;
rem[i] = sum % ((2*i)+1);
carry = ((sum-rem[i])/((2*i)+1))* i;
//printf("decimal:%i i:%i B:%i carry:%i sum:%i rem:%i\n", decimal, i, (2*i)+1, carry, sum, rem[i]); //debugging output
}
sum = (rem[0]*10)+carry;
rem[0] = sum % 10;
pi_digit = (sum - rem[0])/10;
//printf("sum:%i rem:%i\n",sum, rem[i]); //debugging output
if(pi_digit != 10) {
if(pi_digit != 9) {
if(decimal > 0) {
releaseDigits();
}
if(decimal == 1) {
fprintf(f, "."); //shove a point up in that shit
}
blankHeld();
holdDigit(pi_digit);
}
else {
holdDigit(pi_digit);
}
}
else {
incHeld();
releaseDigits();
blankHeld();
holdDigit(0);
}
printf("\r%i/%i decimal places done... ", decimal-1, n-1);
}
deleteLast(); //hide overcompensation
releaseDigits();
fclose(f);
end = clock();
int raw_seconds = (end - start)/1000.;
int seconds = raw_seconds % 60;
int minutes = (raw_seconds - seconds)/60;
printf("\n\nSuccessfully calculated %i decimal places of pi in %i minutes and %i seconds!\nSaved to pi.txt\nPress ENTER to exit the program.\n", n-1, minutes, seconds);
while(getch()!=0x0d);
}
What is happening here?
I used Valgrind, the famous memory checking tool, on your code. Relatively small values (i.e., 10, 100, 1000, even 10000) were no problem. Attempting 156210 instantly made Valgrind complain. It looks like the problem starts with this line:
int rem[((10*n)/3)+2];
The problem is that allocating storage in this manner asks for memory from the stack and this computed value ((10 * 156210 / 3 + 2) = 520702, sizeof(int) = 4 on Windows, so 520702 * 4 = about 2MB) is far more than the machine is prepared to give you from the stack.
If you need this much memory, better to allocate it from the heap using malloc() (don't forget to free() it afterwards).

Resources