So I am making next homework with input numbers to be dissolved to primes multiplication in output. I was confused when it showed up only prime number 2, so I did a proper control dump of the allocated primes array using this function:
long* eratosthen(long max) {
bool grid[max + 1];
for(long i = 0; i < max + 1; ++i) {
grid[i] = true;
}
for(long i = 2; i < max + 1; ++i) {
if(grid[i]) {
for(long j = i * 2; j < max + 1; ++j) {
grid[j] = false;
}
}
}
long *primes;
primes = (long*)malloc((max + 1) * sizeof(long));
long index = 0;
for(long i = 2; i < max + 1; ++i) {
if(grid[i]) {
primes[index++] = i;
}
}
return primes;
}
For some unknown reason, the dump says 2 only and ends. Calling for dump is made up by following code:
int main(void) {
// Prime numbers get calculated first
long *primes;
primes = eratosthen(1000000);
// Control code
fprintf(stdout, "Control dump of primes array:\n");
for(long i = 0; i < sizeof(primes) / sizeof(long); ++i) {
fprintf(stdout, "%li\n", primes[i]);
}
int ret = 0;
/// ...
return ret;
}
//EDIT: So after all your answers I'll update my question to current state. Main program:
int main(void) {
// Prime numbers get calculated first
long *primes;
primes = eratosthen(1000000);
// Control code
fprintf(stdout, "Control dump of primes array:\n");
for( ; *primes != 0 ; primes++) {
fprintf(stdout, "%li\n", *primes);
}
int ret = 0;
}
Generation of primes function:
long* eratosthen(long max) {
bool *grid;
grid = (bool*)malloc((max + 1) * sizeof(bool));
index = 0;
for(long i = 0; i < max + 1; ++i) {
*(grid + index) = true;
index++;
}
index = 2;
index_2 = 2;
for(long i = 2; i < max + 1; ++i) {
if(*(grid + index)) {
for(long j = i * 2; j < max + 1; j += i) {
*(grid + 2 * index_2) = false;
index_2++;
}
index++;
}
}
long *primes;
primes = (long *)malloc((max + 1) * sizeof(long));
index = 0;
for(long i = 0; i < max + 1; ++i) {
*(primes + index) = 0;
index++;
}
index = 0;
index_2 = 2;
for(long i = 2; i < max + 1; ++i) {
if(*(grid + index_2)) {
*(primes + index) = i;
index++;
index_2++;
}
}
// free the grid
free(grid);
return primes;
}
Like said before, the Ubuntu terminal displays following line:
Neoprávněný přístup do paměti (SIGSEGV) (core dumped [obraz paměti uložen])
translated like this:
Forbidden access to memory (SIGSEGV) (core dumped [memory image saved])
What does it mean and how to get rid of that? :(
The simplest fix to your code is probably to add a sentinel value of 0 to the end of the array of primes, and to rewrite the check condition in main(). As explained extensively in the comments, your current test:
for(long i = 0; i < sizeof(primes) / sizeof(long); ++i) {
is irremediably wrong. You must not attempt to use sizeof because it simply doesn't do what you want it to do.
This code works:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
static
long *eratosthen(long max)
{
bool grid[max + 1];
for (long i = 0; i < max + 1; ++i)
grid[i] = true;
for (long i = 2; i < max + 1; ++i)
{
if (grid[i])
{
for (long j = i * 2; j < max + 1; j += i) // Key fix
grid[j] = false;
}
}
long *primes;
primes = (long *)malloc((max + 1) * sizeof(long));
long index = 0;
for (long i = 2; i < max + 1; ++i)
{
if (grid[i])
primes[index++] = i;
}
primes[index] = 0; // Sentinel
return primes;
}
int main(void)
{
// Prime numbers get calculated first
long *primes = eratosthen(1000000);
fprintf(stdout, "Control dump of primes array:\n");
for (long i = 0; primes[i] != 0; ++i)
{
printf("%7li", primes[i]);
if (i % 10 == 9)
putchar('\n');
}
putchar('\n');
return 0;
}
I revised the code to print 10 numbers per line. I changed the condition in the loop in main(). And I made two key changes in the function — one to calculate multiples of primes correctly, and the other to add the sentinel at the end of the list of primes.
It produces a list of 78,498 primes starting with
2 3 5 7 11 13 17 19 23 29
31 37 41 43 47 53 59 61 67 71
73 79 83 89 97 101 103 107 109 113
and ending with:
999563 999599 999611 999613 999623 999631 999653 999667 999671 999683
999721 999727 999749 999763 999769 999773 999809 999853 999863 999883
999907 999917 999931 999953 999959 999961 999979 999983
You might note that the code does not release primes — it arguably should. You might note that the space allocated for the primes greatly exceeds the space needed (one million vs less than eighty thousand); you could use realloc() to shrink the space allocated, or use a less conservative (or do I mean less profligate?) estimate on the number of entries needed.
Related
I'm trying to solve the hacker rank question "Small triangle, Large triangle"
I have to arrange triangle by increasing order of area
the code I wrote is working fine on smaller input given by me but fails on the larger inputs, after taking inputs I just get terminated
eg,
working on input
3
7 24 25
5 12 13
3 4 5
not working when
10
67 67 19
3 57 55
33 33 49
61 58 59
23 43 35
48 42 45
23 12 27
41 34 22
26 49 35
63 46 45
unable to understand why!! Thank YOU!! in advance
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
void sort_by_area(triangle *tr, int n)
{
int *p = (int*)malloc(n * sizeof(int));
int *middle = (int*)malloc((3*n)*sizeof(int));
// doing sum of side of triangle
for (int i = 0; i < n; i++)
{
p[i] = tr[i].a + tr[i].b + tr[i].c;
}
// arranging sum in increasing order
// as more the sum of a+b+c more its area in herons formula
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (p[i] < p[j])
{
int temp;
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
int num = 0;
// storing sides in increasing order in middle
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (p[i] == tr[j].a + tr[j].b + tr[j].c)
{
middle[num] = tr[j].a;
num++;
middle[num] = tr[j].b;
num++;
middle[num] = tr[j].c;
num++;
}
}
}
num=0;
// copying increassed order in tr poiinter in question
for (int i = 0; i < n; i++)
{
tr[i].a = middle[num];
num++;
tr[i].b = middle[num];
num++;
tr[i].c = middle[num];
num++;
}
}
int main()
{
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
It's kind of strange that your function is called sort_by_area but it doesn't seem to calculate any area. Instead it seems to calculate the perimeter of the triangles.
Anyway... there is a bug here. (note: There may be other bugs but to start with you need to fix this)
int *middle = (int*)malloc((3*n)*sizeof(int));
...
...
int num = 0;
// storing sides in increasing order in middle
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (p[i] == tr[j].a + tr[j].b + tr[j].c)
{
middle[num] = tr[j].a;
num++;
middle[num] = tr[j].b;
num++;
middle[num] = tr[j].c;
num++;
}
}
}
You have two nested loops going from 0 to n. When the if statement is true, you increment num 3 times.
So in case p[i] == tr[j].a + tr[j].b + tr[j].c is always true (which is possible), you end up with num being equal to 3*n*n.
And you use num as index into middle but middle is only allocated to hold 3*n integers.
So you are writing outside the allocated area. That's undefined behavior.
BTW
When sorting arrays in C you should nearly always use qsort
/Write a program to determine the total number of prime numbers below 1000,000,000 have the sum of their digits equal to 14? Make sure the execution time is few seconds./
#include<stdio.h>
#include<math.h>
int main() {
int i, j, count = 0, temp = 0, n, ans = 0, tot = 0;
for (i = 1; i <= 1000000000; i++) {
for (j = 2; j <= i / 2; j++) {
if (i % j == 0) {
count++;
}
}
if (count == 0) {
n = i;
while (n != 0) {
temp = n % 10;
n = n / 10;
ans = ans + temp;
}
if (ans == 14) {
tot++;
printf("%d,", i);
}
ans = 0;
temp = 0;
}
count = 0;
}
// printf("%d:\n",tot);
return 0;
}
Two simply improvements (amongst other):
1: Rather than iterate to i/2, iterate to the square root of i - that is j*j <= i.** This is a huge speed-up.
2: Quit loop once a factor found.
// for(j=2;j<=i/2;j++) {
// if(i%j==0) {
// count++;
// }
//}
for(j=2;j<=i/j;j++) { // _much_ lower limit
if(i%j==0) {
count++;
break; // No need to find more factors: `i` is not a prime.
}
}
Functionality: Inside if(count==0), I'd expect ans == 0 before while(n!=0).
** Use j<=i/j to prevent overflow. A good compiler will see a nearby i%j and often perform both i/j, i%j for the time cost of one.
The digit-sum function could also use a early return like:
int dsum14(int n) {
int sum = 0;
for (; n; n /= 10)
if ((sum += n % 10) > 14)
return 0;
return sum == 14 ? 1 : 0;
}
But how to combine the (efficient) prime search and this sum condition?
int n, cnt = 0;
for (n = 3; n < 1000*1000*1000; n += 2)
if (n%3 && n%5 && dsum14(n) && n%7 && n%11 && n%13)
cnt++;
This gives 77469 in 1.5 seconds. With dsum() at either end of the logical chain it is almost double.
The && n%7 && n%11 && n%13 part would be replaced by a function using a list of primes up to about 32000 (square root of max).
...or you can optimize it to 0.1 seconds, by tweaking the digsum function.
There are "only" 575 three-digit numbers 000-999 with sum 14 or less. So I prepare them and combine three of them to get a 9-digit number. Generating them instead of filtering them.
The tail looks like:
920000021
920000201
920001011
920010011
920100011
920100101
920101001
921001001
931000001
total count: 22588
real 0m0.098s
user 0m0.100s
sys 0m0.002s
And the start:
59
149
167
239
257
293
347
383
419
Not 100% sure if it's correct, but the total count also seems reasonable.
It all relies on the given max of 1000 Mio. digsum_prime() uses it to build the candidate number from three (almost) equal parts.
Code:
#include <stdio.h>
#include <stdlib.h>
int parr[5000] = {3};
struct {
int tri, sum;
} ts[999];
void primarr(void) {
int maxn = 32000;
int i = 1;
for (int n = 5; n < maxn; n += 2)
for (int div = 3;; div += 2) {
if (!(n % div))
break;
if (div*div > n) {
parr[i++] = n;
break;
}
}
}
int isprime(int n) {
for(int i = 0;; i++) {
if (!(n % parr[i]))
return 0;
if (parr[i]*parr[i] > n)
return 1;
}
}
int dsum(int n) {
int sum = 0;
for (; n; n /= 10)
sum += n % 10;
return sum;
}
int tsarr(void) {
int i = 0;
for (int n = 0; n < 1000; n++) {
int digsum = dsum(n);
if (digsum <= 14) {
ts[i].tri = n;
ts[i].sum = digsum;
i++;
}
}
return i;
}
int digsum_prime() {
int cnt = 0;
int tslen = tsarr();
printf("tslen: %d\n", tslen);
int high, mid, low;
int sum, num;
for (high = 0; high < tslen; high++) {
if(ts[high].sum > 13)
continue;
for (mid = 0; mid < tslen; mid++) {
if(ts[mid].sum + ts[high].sum > 13)
continue;
sum = ts[mid].sum + ts[high].sum;
for (low = 0; low < tslen; low++)
if (ts[low].tri % 2)
if(ts[low].sum + sum == 14) {
num = ts[high].tri * 1000*1000
+ ts[mid] .tri * 1000
+ ts[low] .tri;
if (isprime(num)) {
cnt++;
printf("%d\n", num);
}
}
}
}
return cnt;
}
int main(void) {
primarr();
printf("total count: %d\n", digsum_prime());
}
Changing 13-13-14 to 3-3-4 (but same preparation part) gives an overview - in 0.005 s!
tslen: 575
13
31
103
211
1021
1201
2011
3001
10111
20011
20101
21001
100003
102001
1000003
1011001
1020001
1100101
2100001
10010101
10100011
20001001
30000001
101001001
200001001
total count: 25
real 0m0.005s
user 0m0.005s
sys 0m0.000s
Make sure the execution time is few seconds.
oops
But the limits of OP are well chosen: a naive approach takes several seconds.
I created a cross-correlation algorithm, and I am trying to maximize its performance by reducing the time it takes for it to run. First of all, I reduced the number of function calls within the "crossCorrelationV2" function. Second, I created several macros at the top of the program for constants. Third, I reduced the number of loops that are inside the "crossCorrelationV2" function. The code that you see is the most recent code that I have.
Are there any other methods I can use to try and reduce the processing time of my code?
Let's assume that I am only focused on the functions "crossCorrelationV2" and "createAnalyzingWave".
I would be glad for any advice, whether in general about programming or pertaining to those two specific functions; I am a beginner programmer. Thanks.
#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE 4096
#define PULSESNUMBER 16
#define DATAFREQ 1300
// Print the contents of the array onto the console.
void printArray(double array[], int size){
int k;
for (k = 0; k < size; k++){
printf("%lf ", array[k]);
}
printf("\n");
}
// Creates analyzing square wave. This square wave has unity (1) magnitude.
// The number of high values in each period is determined by high values = (analyzingT/2) / time increment
void createAnalyzingWave(double analyzingFreq, double wave[]){
int highValues = (1 / analyzingFreq) * 0.5 / ((PULSESNUMBER * (1 / DATAFREQ) / ARRAYSIZE));
int counter = 0;
int p;
for(p = 1; p <= ARRAYSIZE; p++){
if ((counter % 2) == 0){
wave[p - 1] = 1;
} else{
wave[p - 1] = 0;
}
if (p % highValues == 0){
counter++;
}
}
}
// Creates data square wave (for testing purposes, for the real implementation actual ADC data will be used). This
// square wave has unity magnitude.
// The number of high values in each period is determined by high values = array size / (2 * number of pulses)
void createDataWave(double wave[]){
int highValues = ARRAYSIZE / (2 * PULSESNUMBER);
int counter = 0;
int p;
for(p = 0; p < ARRAYSIZE; p++){
if ((counter % 2) == 0){
wave[p] = 1;
} else{
wave[p] = 0;
}
if ((p + 1) % highValues == 0){
counter++;
}
}
}
// Finds the average of all the values inside an array
double arrayAverage(double array[], int size){
int i;
double sum = 0;
// Same thing as for(i = 0; i < arraySize; i++)
for(i = size; i--; ){
sum = array[i] + sum;
}
return sum / size;
}
// Cross-Correlation algorithm
double crossCorrelationV2(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
double bigAnalyzingArray[bigArraySize];
int i;
int b;
// Set first few elements of the array equal to analyzingWave
// Set remainder of big analyzing array to 0
for(i = 0; i < ARRAYSIZE; i++){
bigAnalyzingArray[i] = analyzingWave[i];
bigAnalyzingArray[i + ARRAYSIZE] = 0;
}
double maxCorrelationValue = 0;
double currentCorrelationValue;
// "Beginning" of correlation algorithm proper
for(i = 0; i < bigArraySize; i++){
currentCorrelationValue = 0;
for(b = lastBigArrayIndex; b > 0; b--){
if (b >= lastArrayIndex){
currentCorrelationValue = dataWave[b - lastBigArrayIndex / 2] * bigAnalyzingArray[b] + currentCorrelationValue;
}
bigAnalyzingArray[b] = bigAnalyzingArray[b - 1];
}
bigAnalyzingArray[0] = 0;
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
return maxCorrelationValue;
}
int main(){
int samplesNumber = 25;
double analyzingFreq = 1300;
double analyzingWave[ARRAYSIZE];
double dataWave[ARRAYSIZE];
createAnalyzingWave(analyzingFreq, analyzingWave);
//createDataWave(arraySize, pulsesNumber, dataWave);
double maximumCorrelationArray[samplesNumber];
int i;
for(i = 0; i < samplesNumber; i++){
createDataWave(dataWave);
maximumCorrelationArray[i] = crossCorrelationV2(dataWave, analyzingWave);
}
printf("Average of the array values: %lf\n", arrayAverage(maximumCorrelationArray, samplesNumber));
return 0;
}
The first point is that you are explicitly shifting the analizingData array, this way you are required twice as much memory and moving the items is about 50% of your time. In a test here using crossCorrelationV2 takes 4.1 seconds, with the implementation crossCorrelationV3 it runs in ~2.0 seconds.
The next thing is that you are spending time multiplying by zero on the padded array, removing that, and also removing the padding, and simplifying the indices we end with crossCorrelationV4 that makes the program to run in ~1.0 second.
// Cross-Correlation algorithm
double crossCorrelationV3(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
double bigAnalyzingArray[bigArraySize];
int i;
int b;
// Set first few elements of the array equal to analyzingWave
// Set remainder of big analyzing array to 0
for(i = 0; i < ARRAYSIZE; i++){
bigAnalyzingArray[i] = analyzingWave[i];
bigAnalyzingArray[i + ARRAYSIZE] = 0;
}
double maxCorrelationValue = 0;
double currentCorrelationValue;
// "Beginning" of correlation algorithm proper
for(i = 0; i < bigArraySize; i++){
currentCorrelationValue = 0;
// Instead of checking if b >= lastArrayIndex inside the loop I use it as
// a stopping condition.
for(b = lastBigArrayIndex; b >= lastArrayIndex; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue = dataWave[b - lastBigArrayIndex / 2] * bigAnalyzingArray[b - i] + currentCorrelationValue;
}
bigAnalyzingArray[0] = 0;
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
return maxCorrelationValue;
}
// Cross-Correlation algorithm
double crossCorrelationV4(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
// I will not allocate the bigAnalizingArray here
// double bigAnalyzingArray[bigArraySize];
int i;
int b;
// I will not copy the analizingWave to bigAnalyzingArray
// for(i = 0; i < ARRAYSIZE; i++){
// bigAnalyzingArray[i] = analyzingWave[i];
// bigAnalyzingArray[i + ARRAYSIZE] = 0;
// }
double maxCorrelationValue = 0;
double currentCorrelationValue;
// Compute the correlation by symmetric paris
// the idea here is to simplify the indices of the inner loops since
// they are computed more times.
for(i = 0; i < lastArrayIndex; i++){
currentCorrelationValue = 0;
for(b = lastArrayIndex - i; b >= 0; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue += dataWave[b] * analyzingWave[b + i];
}
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
if(i != 0){
currentCorrelationValue = 0;
// Correlate shifting to the other side
for(b = lastArrayIndex - i; b >= 0; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue += dataWave[b + i] * analyzingWave[b];
}
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
}
return maxCorrelationValue;
}
If you want more optimization you can unroll some iterations of the loop and enable some compiler optimizations like vector extension.
Goldbach's conjecture states that every even integer over 4 is the sum of two primes, I am writing a program in C to find these pairs. To do this it first finds all the primes less than a user given number. I have a for loop to iterate from 4 to the user given number and find the pairs within the loop body. When that loop gets to about around 40, suddenly jumps back down by about 30 and then continues to iterate up (with user input 50 it jumped from 38 to 9, with input 60 it jumped from 42 to 7). I can't figure out why this is happening. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
struct pair{
int a;
int b;
}pair_t;
int main(){
int N;
int numPrimes = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
struct pair pairs[N/2 + 4];
int j = 0;
int i;
for (i = 3; i <= N; i+=2){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[numPrimes] = i;
numPrimes++;
}
if (availableSlots == numPrimes){
timesRealloc++;
availableSlots += 100;
primes = realloc(primes, availableSlots*sizeof(int));
}
}
printf("The largest prime I found was %d\n", primes[(numPrimes-1)]);
int k;
for (i=4; i<=N; i+=2){
printf("i is %d, N is %d\n", i, N);
if (i > N){ break; }
for (j=0; j<numPrimes; j++){
for (k=0; k<numPrimes; k++){
int sum = primes[j] + primes[k];
if(sum == i){
pairs[i].a = primes[j];
pairs[i].b = primes[k];
}
}
}
}
for (i=4; i<=N; i+=2){
printf("%d is the sum of %d and %d\n", i, pairs[i].a, pairs[i].b);
}
return 0;
}
You attempt to be space efficient by compressing the pairs array to just hold every other (even) number and start from 4 instead of zero. However, you miscalculate its size and then when you go to use it, you treat it like it hasn't been compressed and that there's a slot for every natural number.
The code suffers from having the prime array calculation in main() along with the other code, this is best separated out. And when it looks for pairs, it doesn't quit when it finds one, nor when it starts getting sums greater than the target. My rework below attempts to address all of these issues:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define INITIAL_SLOTS (100)
struct pair {
int a;
int b;
} pair_t;
int compute_primes(int limit, unsigned **primes, int size) {
int numPrimes = 0;
(*primes)[numPrimes++] = 2;
for (int i = 3; i <= limit; i += 2) {
bool isPrime = true;
for (int j = 0; (*primes)[j] <= i / (*primes)[j]; j++) {
if (i % (*primes)[j] == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
(*primes)[numPrimes++] = i;
}
if (numPrimes == size) {
size *= 2;
*primes = realloc(*primes, size * sizeof(unsigned));
}
}
return numPrimes;
}
int main() {
int N;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
unsigned *primes = calloc(INITIAL_SLOTS, sizeof(unsigned));
int numPrimes = compute_primes(N, &primes, INITIAL_SLOTS);
printf("The largest prime I found was %d\n", primes[numPrimes - 1]);
struct pair pairs[(N - 4) / 2 + 1]; // compressed data structure
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
bool found = false;
for (int j = 0; ! found && j < numPrimes; j++) {
for (int k = 0; ! found && k < numPrimes; k++) {
int sum = primes[j] + primes[k];
if (sum == i) {
pairs[offset].a = primes[j];
pairs[offset].b = primes[k];
found = true;
} else if (sum > i) {
break;
}
}
}
}
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
printf("%d is the sum of %d and %d\n", i, pairs[offset].a, pairs[offset].b);
}
free(primes);
return 0;
}
OUTPUT
> ./a.out
Please enter the largest even number you want to find the Goldbach pair for:
10000
The largest prime I found was 9973
4 is the sum of 2 and 2
6 is the sum of 3 and 3
8 is the sum of 3 and 5
10 is the sum of 3 and 7
12 is the sum of 5 and 7
14 is the sum of 3 and 11
...
9990 is the sum of 17 and 9973
9992 is the sum of 19 and 9973
9994 is the sum of 53 and 9941
9996 is the sum of 23 and 9973
9998 is the sum of 31 and 9967
10000 is the sum of 59 and 9941
>
This c program is working fine in windows but showing segment fault in Linux.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
void comb(long int *arr,long int n,long int r,long int stick)
{
long int check=1,sum =0;
int poscheck = 0,status = 0;
long int *temp = malloc(r * sizeof(long int));
long int *pos = malloc(r * sizeof(long int));
long int *rept = malloc(r * sizeof(long int));
memset(pos, 0, r*sizeof(long int));
memset(rept, 0, r*sizeof(long int));
while (check <= pow(n,r))
{
for (long int i = 0; i < r; i++) //for making the number of array
{
for(long int j = 0; j < r; j++) //For checking that no number is repeating.
{
if(i == j) continue; //for skip checking of the same element
else if(pos[i] == pos[j])
{
poscheck = 1;
break;
}
}
if(poscheck == 1) break;
temp[i] = arr[pos[i]];
sum += temp[i];
}
if((sum == stick) && poscheck == 0)
{
for(long int i = 0 ; i< r ; i++)
{
printf("%ld ",temp[i]);
}
status = 1;
printf("\n");
break;
}
sum = 0,poscheck = 0;
for (long int i = 0; i < r; i++)
{
if (pos[i] == n - 1)
{
rept[i]++; //To check how much time the number is repeated in a column
}
if ((pos[i] == n - 1) && (rept[i] == pow(n, r-i-1))) //If it is repeated a specific number of time then change the value of it's previous position
{
if (pos[i - 1] == n - 1) //if the previous number is the last number then it will start the series again
{
pos[i - 1] = 0;
}
else
pos[i - 1]++; //If the previous number is not the last number of series then go to the next number
rept[i] = 0;
}
}
if (pos[r - 1] < n - 1) //for go to the next number of series in the last line
{
pos[r - 1]++;
}
else
{
pos[r - 1] = 0; //if it is the last number of series then start form the first again
}
check++;
}
if(status == 0)
{
printf("-1\n");
}
free(pos); //Does not know why this is showing "double free or corruption (out)" in linux but working in windows.
free(rept);
free(temp);
}
int main()
{
long int n,data[3],j=0;
scanf("%ld",&n);
long int *arr = malloc(n*sizeof(long int));
while(j < n)
{
for(long int i = 0; i< 3; i++)
{
scanf("%ld",&data[i]);
}
for(long int i = 0; i < data[1]; i++)
{
arr[i] = i+1;
}
comb(arr,data[1],data[2],data[0]);
j++;
}
free (arr);
return 0;
}
The given input is
12 8 3
10 3 3
9 10 2
9 10 2
This is showing in linux
1 3 8
-1
munmap_chunk(): invalid pointer
Aborted (core dumped)
This is showing perfectly in windows
2 3 7
-1
5 4
1 8
I used gcc and tcc both compiler in windows and Linux but both are giving same error in Linux.
Can't understand why the problem is showing in Linux.
If the input is
1 3 8
-1
in main
n = 1
arr = memory for 1 long int
in for(long int i = 0; i< 3; i++)
data array = 3 8 -1
in: for(long int i = 0; i < data[1]; i++)
arr[i] = some value
But arr array will iterate 8 times and attempt to assign arr[i], even though arr has one element.
for the lines starting with:
if (pos[i - 1] == n - 1)
`i' will be 0 at times (on the input of 10 3 3) and so at that point you are setting pos[-1] to values - ie: setting memory you shouldn't be to something which is then interfering with the free later on as malloc uses values before the pointer for free information.
To validate,, if I added a print before the if compare and run your example:
if(i==0) printf("bad I pos\n");
It prints out in a number places before having the error.