I used GNU BC ( basic calculator ) for exponentiation 999,999 to 999,999 and it answered in 10 minutes but when I want to find 999,999 root of a big file ( 1.1 GB) it shows segfault after 5 hours and GDB core shows mpz_clear(y) is the problem and when I remove it , It takes 20 hours and nothing happens and loop doesn't finish ; Here's the code :
#include <gmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE *fr, *fw;
char filename[200];
int size = 0;
unsigned long int rt = 2;
unsigned char ch[1] = {112};
printf("Enter filename :\n");
scanf("%s", &filename);
fr = fopen(filename, "rb+");
if (fr == NULL) {
fprintf(stderr, "Error during opening of file %s\n", filename);
perror("");
return 1;
}
fseek(fr, 0L, SEEK_END);
size = ftell(fr);
fseek(fr, 0L, SEEK_SET);
unsigned char* buf = NULL;
buf = malloc((size_t)size);
fread(buf, size, 1, fr);
if (ferror(fr)) {
fprintf(stderr, "Error during reading from file %s\n", filename);
perror("");
fclose(fr);
return 1;
}
fclose(fr);
fr = NULL;
mpz_t x;
mpz_init(x);
mpz_t y;
mpz_init(y);
mpz_import(x, size, 1, (size_t)1u, 0, 0, buf);
do {
mpz_root(y, x, rt);
if ((mpz_cmp_ui(y, 999999)) < 0)
break;
else
mpz_clear(y);
rt++;
} while (rt <= 99999);
int rootnum = 0;
while (rt != 0) {
int num;
num = rt / 10;
++rootnum;
}
memset(buf, 0u, size);
mpz_export(buf, NULL, 1, (size_t)1u, 0, 0, y);
printf("Enter copied filename :\n");
scanf("%s", &filename);
fw = fopen(filename, "wb");
if (fw == NULL) {
fprintf(stderr, "Error during opening of file %s\n", filename);
perror("");
return 1;
}
fwrite(buf, mpz_sizeinbase(y, 10), 1, fw);
if (ferror(fw)) {
fprintf(stderr, "Error during writing to file %s\n", filename);
perror("");
fclose(fw);
return 1;
}
fclose(fw);
fw = fopen(filename, "ab+");
fwrite(ch, 1, 1, fw);
fclose(fw);
fw = fopen(filename, "ab+");
fwrite(&rt, rootnum, 1, fw);
fclose(fw);
free(buf);
mpz_clear(x);
mpz_clear(y);
return 0;
}
Can any one tell me why the loop doesn't finish and how to fix it ?
Thanks I will be grateful
Edit : The code has been changed but segfault still exist and when I use GDB for debugging and open core file and enter the where command GDB shows mpz_clear(y) and if I remove it ( of course with else option ) the loop never ends ; The new code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <gmp.h>
int main(void)
{
FILE * fr, * fw;
char filename[201];
unsigned long long int size = 0;
unsigned long int rt = 2;
unsigned char ch[1] = {112};
printf("Enter filename : ");
fgets(filename, 200, stdin);
filename[strlen (filename) - 1] = '\0';
fr = fopen(filename, "rb+");
if (fr == NULL)
{
fprintf(stderr, "Error during opening of file %s\n", filename);
perror("");
return 1;
}
fseek(fr, 0L, SEEK_END);
size = ftell(fr);
fseek(fr, 0L, SEEK_SET);
if (size == -1)
{
fprintf(stderr, "Size doesn't match\n'");
perror("");
return 1;
}
if ( size > SIZE_MAX)
{
fprintf(stderr, "The size of file is greater than acceptable\n");
perror("");
return 1;
}
unsigned char * buf = NULL;
buf = malloc((size_t)size);
if(buf == NULL)
{
fprintf(stderr, "Buffer failure\n");
perror("");
return 1;
}
int r;
r = fread(buf, size, 1, fr);
printf("%d\n", r);
if (ferror(fr))
{
fprintf(stderr, "Error during reading from file %s\n", filename);
perror("");
fclose(fr);
return 1;
}
fclose(fr);
fr = NULL;
mpz_t x;
mpz_init(x);
mpz_t y;
mpz_init(y);
mpz_import(x, size, 1, (size_t)1u, 0, 0, buf);
do
{
mpz_root (y, x, rt);
if ((mpz_cmp_ui(y, 999999))<0)
break;
else
{
mpz_clear(y);
mpz_init(y);
rt++;
}while(rt<=99999);
int rootnum = 0;
unsigned long int num = rt;
do
{
num = num/10;
++rootnum;
}while(num != 0);
memset (buf, 0u, size);
mpz_export(buf, NULL, 1, (size_t)1u, 0, 0, y);
printf("\nEnter copied filename : ");
fgets(filename, 200, stdin);
filename[strlen (filename) - 1] = '\0';
fw = fopen(filename, "wb");
if (fw == NULL) {
fprintf(stderr, "Error during opening of file %s\n", filename);
perror("");
return 1;
}
fwrite(buf, mpz_sizeinbase(y, 10), 1, fw);
if (ferror(fw)) {
fprintf(stderr, "Error during writing to file %s\n", filename);
perror("");
fclose(fw);
return 1;
}
fclose(fw);
fw = fopen(filename, "ab+");
if(fw == NULL)
printf("File can't be written\n'");
if(ferror(fw))
{
fprintf(stderr, "Error during writing to file %s\n", filename);
perror("");
fclose(fw);
return 1;
}
fwrite(ch, 1, 1, fw);
fclose(fw);
fw = fopen(filename, "ab+");
if(fw == NULL)
printf("File can't be written\n'");
if(ferror(fw))
{
fprintf(stderr, "Error during writing to file %s\n", filename);
perror("");
fclose(fw);
return 1;
}
int w;
w = fwrite(&rt, rootnum, 1, fw);
printf("%d\n", w);
fclose(fw);
free(buf);
mpz_clear(x);
mpz_clear(y);
return 0;
}
{}even for single statementifs, to make more obvious what you think your code is doing. Also, some indentation would help with that (though it does NOT actually influence behaviour, other than in e.g. Python). Probably becaue of your use ofbreakit won't matter, even if you are wrong about howifworks without{}, but it would make reading so much easier.compressiontag relevant to this?scanf("%s", &filename);should bescanf("%199s", filename);.%sexpects achar*but you give it achar(*)[200]. Better usefgets