Spliting string to an array in C - c

int main()
{
int longNum = 12345, tempNum[5], i;
for (i = 0; i <= 5; i++)
{
tempNum[i] = longNum[i] ; // not valid, how do i make this work?
}
printf("%d\n", tempNum);
return 0;
}
Im trying to go through all the digits of longNum and push them into tempNum[].

You may try the modulo operator:
int main()
{
int longNum = 12345, tempNum[5], i;
for (i = 4; i >= 0; i--)
{
tempNum[i] = longNum % 10;
longNum /= 10;
}
for( i = 0; i < 5; i++ )
{
printf("%d\n", tempNum[i]);
}
return 0;
}

For a dynamic length:
#include <stdio.h>
#include <stdlib.h>
int main()
{
long long longNum = 1234512345; // can be any size within `long long` limit.
int tempNum[5], i;
int num_digits = 0;
long temp = longNum;
while( temp > 0 )
{
temp /= 10;
num_digits++;
}
printf( "num_digits = %d\n", num_digits );
// Allocate dynamic array.
int *pos = malloc( num_digits * sizeof( int ) );
for( i = num_digits - 1; i >= 0; i-- )
{
pos[i] = longNum % 10;
longNum /= 10;
}
for( i = 0; i < num_digits; i++ )
{
printf("%d\n", pos[i]);
}
return 0;
}

You could try this:
int main( )
{
int longNum = 12345, tempNum[5], i;
char numstr[99];
itoa( longNum, numstr, 10 );
for ( i = 0; i < 5; i++ )
{
tempNum[i]=numstr[i] - '0';
printf( "\n%d", tempNum[i] );
}
return 0;
}

#include <stdio.h>
int main()
{
int longNum = 12345, tempNum[5], i;
for (i = 1; i <= 5; i++)
{
tempNum[5-i] = longNum % 10;
longNum = longNum/10;
}
printf("%d%d%d%d%d\n", tempNum[0], tempNum[1], tempNum[2], tempNum[3], tempNum[4]);
return 0;
}

Related

I am trying to solve a special travelling salesman problem with mpi and c

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <mpi.h>
#define MaxSize 50
typedef int ElementType;
typedef int Position;
typedef int Status;
typedef struct SeqStack
{
ElementType Data[MaxSize];
Position Top;
int (*Push)(struct SeqStack *L);
int (*Pop)(struct SeqStack *L , int e);
int (*isEmpty)(struct SeqStack s);
Status (*isFull)(struct SeqStack s);
}SeqStack;
int Push(SeqStack *L)
{
if(L->Top == 0)
{
return 0;
}
printf("%d ",L->Data[--L->Top]);
return 1;
}
int Pop(SeqStack *L , int e)
{
if(L->Top==MaxSize -1)
{
return 0;
}
L->Data[L->Top++] = e;
return 1;
}
int isEmpty(SeqStack s)
{
if(s.Top != 0)
{
return 1;
}
return 0;
}
Status isFull(SeqStack s)
{
if(s.Top != MaxSize -1)
{
return 1;
}
return 0;
}
int global_max;
int ans = INT_MAX;
void *tsp(int Dis[global_max][global_max],int v[],int N,int count,int currPos,int cost,int sum,int* result,int temp[],int make_log){
temp[0]=1;
//int mode;
//printf("count:%d\n",count);
if(count == N&&Dis[currPos][1]>0){
//printf("Ans:%d,cost:%d\n",ans,cost);
if(make_log == 1){
char str[100]={'\0'};
char output[100]={'\0'};
//printf("Ans:%d,cost:%d\n",ans,cost);
FILE *log;
for(int i=0; i<N;i++){
if (i!=N-1){
sprintf(str,"%d",temp[i]);
strcat(output,str);
strcat(output,",");
}else{
sprintf(str,"%d",temp[i]);
strcat(output,str);
strcat(output,"=");
}
}
sprintf(str,"%d",cost);
strcat(output,str);
strcat(output,"\n");
log=fopen("log.txt","a");
fputs(output,log);
fclose(log);
}
if(sum> cost){
sum = cost;
ans = cost;
//printf("every ans is %d\n\n\n\n",ans);
for (int i=0;i<N;i++){
//printf("temp[%d]=%d,",i,temp[i]);
result[i]=temp[i];
//printf("result[%d]=%d,",i,result[i]);
}
}
//ans = min(ans,cost + Dis[1][currPos]);
return result;
}
for (int i = 1;i<N+1;i++){
//printf("!!!!!!! v[%d] = %d\n",i,v[i]);
if(v[i]==0&&Dis[currPos][i]>0){
//printf("cost + Dis: %d + %d\n",cost,Dis[currPos][i]);
if(cost + Dis[currPos][i] <= ans||count==N-1){
v[i] = 1;
temp[count] = i;
//printf("\ntemp[%d] = %d\n",count,temp[count]);
//printf("currPos:%d,i:%d,count:%d\n",currPos,i,count);
//printf("Ans:%d,cost:%d\n",ans,cost);
result = tsp(Dis,v,N,count + 1,i,cost + Dis[currPos][i],sum,result,temp,make_log);
//mode = 0;
v[i]= 0;
if(count==1){
for(int j = 2;j<N+1;j++){
v[j]= 0;
}
}
}else{
//printf("currPos:%d,i:%d,count:%d\n",currPos,i,count);
temp[count] = i;
for (int k = N-1;k>count;k--){
temp[k] = 0;
}
int v_copy[N];
for (int o = 1;o<N+1;o++){
v_copy[o] = v[o];
// if(currPos==3&&i==4){
// printf("v_copy[%d] = %d//",o,v_copy[o]);
// }
}
for(int j = 2;j< N + 1;j++){
if(v[j]==0){
v[j] = 1;
}
}
result = tsp(Dis,v,N,N,N,cost + Dis[currPos][i],sum,result,temp,make_log);
//printf("Fuck currpos:%d\n",currPos);
for (int o = 1;o<N+1;o++){
v[o] = v_copy[o];
// if(currPos==3&&i==2){
// printf("v[%d] = %d//",o,v[o]);
// }
}
if(count==1){
for(int j = 2;j<N+1;j++){
v[j]= 0;
}
}
}
}
}
return result;
};
void change(int n){
global_max = n;
};
int main(int argc, char const *argv[])
{
int N;
int size = 1;
int count = 1;
int log = 0;
int nthreads,my_rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nthreads);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(argc > 2){
log = 1;
}
char x[100] = {0};
char filename[100] = {};
strcat(filename,argv[1]);
strcat(filename,".txt");
//printf("%s\n",filename);
FILE *fp=fopen(filename,"r");
if(fp==NULL){
printf("Cannot open the file,strike any key to exit!\n");
getchar();
exit(0);
}
for (int i = 0;!feof(fp);i++){
fscanf(fp,"%hhd",&x[i]);
}
N=x[0];
change(N);
int* result;
result = (int *)malloc(sizeof(int) * global_max);
int Dis[N][N], City[N];
for(int i=1;i<N;i++){
size=size*i;
}
char y[size];
for (int i=1;i<size+1;i++){
y[i] = x[i];
//printf("%d\n",y[i]);
}
for(int i=2; i < N + 1; i++){
for(int j=1; j < i ; j++){
Dis[j][i] = y[count];
Dis[i][j] = y[count];
count+=1;
//printf("(%d,%d),(%d,%d)",j,i,i,j);
//printf("%d\n",Dis[j][i]);
}
}
for(int i=0;i<N;i++){
City[i]=i + 1;//create the number of city with 1 ...... N
}
int curr_constraint = 0;
int v[N+1];
for (int i = 1; i < N+1; i++){
v[i] = 0;
}
for(int i = 1;i<N+1;i++){
curr_constraint += Dis[i][i+1];
}
v[1]= 1;
int sum = INT_MAX;
//printf("orginal ans is %d\n",ans);
//printf("Dis map:\n");
for( int i= 1;i<N+1;i++){
for(int j =1;j<N+1;j++){
if(i==j){
Dis[i][j]=0;
}
//printf("%d ",Dis[i][j]);
}
//printf("\n");
}
//printf("The orginal constraint is %d\n",curr_constraint);
int temp[N];
int* city_divided;
int cityNumber;
int current_ans;
SeqStack s;
if(nthreads > 1){
int remain = N % (nthreads - 1);
//int group_n = N /(nthreads - 1);
if(remain !=0){
if(my_rank <= remain && my_rank != 0){
cityNumber = ((N - remain)/(nthreads - 1)) + 1;
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}else{
cityNumber = ((N - remain) / (nthreads - 1));
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}
}else{
cityNumber = N / (nthreads - 1);
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}
if(my_rank==0){
MPI_Recv(&ans, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for(int i=0;i<N;i++){
if(i != N-1){
printf("%d,",*(result+i));
}
else{
printf("%d",*(result+i));
}
}
printf("\n");
printf("Distance: %d\n",ans);
}
if(my_rank!=0){
for (int i = 0 ; i<cityNumber;i++){
current_ans = ans;
while(s.isEmpty(s)){
MPI_Recv(&ans, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
result = tsp(Dis,v,N,1,city_divided[i],0,ans,result,temp,log);
s.Pop(&s,ans);
}
result = tsp(Dis,v,N,1,city_divided[i],0,ans,result,temp,log);
if(current_ans - ans > 0){
s.Push(ans);
MPI_Bcast(&ans,1,MPI_INT,0,MPI_COMM_WORLD);
}
}
}
}
else{
result = tsp(Dis,v,N,1,1,0,sum,result,temp,log);
}
for(int i=0;i<N;i++){
if(i != N-1){
printf("%d,",*(result+i));
}
else{
printf("%d",*(result+i));
}
}
printf("\n");
printf("Distance: %d\n",ans);
return 0;
}
I am trying to solve a special travelling salesman problem with mpi and c. I want make the master processor print the final information including the route and the shorest distance. the other processors with all city group run the tsp function, and when it has the shorter distance, use mpi_send or mpi_Bcast to other processors.Follow this logic, I meet a problem when I run the program.
enter image description here

In C, I'm having trouble getting an Index sorted High to Low and vice versa

I'm working on a project involving a preset array:
primaryArray[8] = {8, 4, 2, 16, 32, 124, 64, 256};
Im calling a function before the main, its not quite working. Here is the code.
void lowhighSort(int primaryArray[], int arrayLength) {
int i;
int a;
int indexMin;
for (i = 0; i < arrayLength - 1; ++i){
indexMin = i;
for (a = (i + 1) + 1; a < arrayLength; ++a) {
if (primaryArray[a] < primaryArray[indexMin]){
indexMin = a;
}
simpleSwap(&primaryArray[indexMin], &primaryArray[i]);
}
}
}
void highlowSort(int primaryArray[], int arrayLength) {
int i;
int a;
int indexMin;
for (i = 0; i < arrayLength - 1; ++i){
indexMin = i;
for (a = i + 1; a < arrayLength; ++a) {
if(primaryArray[a] > primaryArray[indexMin])
indexMin = a;
simpleSwap(&primaryArray[indexMin], &primaryArray[i]);
}
}
}
My "simpleSwap" might be the mistake, when learning I didn't quite understand entirely what the * did. Regardless, here it is as well:
void simpleSwap(int* x, int* y) {
int temp = *x;
*x = *y;
*y = temp;
}
*edit
This is part of a "larger" code so I'm not entirely sure if perhaps the error is elsewhere.
#include <stdio.h>
#include <stdlib.h>
void simpleSwap(double* x, double* y) {
double temp = *x;
*x = *y;
*y = temp;
}
double largest(double Array[], double Length) {
double largestNum = Array[0];
for (int i = 1; i < Length; ++i) {
if(largestNum < Array[i]) {
largestNum = Array[i];
}
}
return largestNum;
}
double smallest(double Array[], double Length) {
double smallestNum = Array[0];
for (int i = 1; i < Length; ++i) {
if(smallestNum > Array[i]) {
smallestNum = Array[i];
}
}
return smallestNum;
}
void lowhighSort(double Array[], double Length) {
int a;
int indexMin;
for (int i = 0; i < Length; ++i){
indexMin = i;
for (a = (i + 1); a < Length; ++a) {
if (Array[a] < Array[indexMin]){
indexMin = a;
simpleSwap(&Array[indexMin], &Array[i]);
}
}
}
}
void highlowSort(double Array[], double Length) {
int a;
int indexMin;
for (int i = 0; i < Length; ++i){
indexMin = i;
for (a = (i + 1); a < Length; ++a) {
if(Array[a] > Array[indexMin]){
indexMin = a;
simpleSwap(&Array[indexMin], &Array[i]);
}
}
}
}
float arrayAverage (double Array[], double Length) {
int i;
double arrayAverage = 0;
for (i = 0; i < Array[i]; ++i) {
arrayAverage = Array[i] + arrayAverage;
}
return arrayAverage;
}
int main()
{
double primaryArray[8] = {8, 4, 2, 16, 32, 124, 64, 256};
double arrayLength = sizeof(primaryArray)/sizeof(primaryArray[0]);
double ancillaryArray[10] = {8, 4, 2, 16, 32, 124, 64, 256};
printf("Primary Array:\n");
printf("\nLargest Array Element: %.1lf\n", largest(primaryArray, arrayLength));
printf("Smallest Array Element: %.1lf\n\n", smallest(primaryArray, arrayLength));
lowhighSort(primaryArray, arrayLength);
printf("Array Ascending Order: ");
for(int i = 0; i < 8; ++i){
printf("%.1lf, ", primaryArray[i]);
}
printf("\n");
highlowSort(primaryArray, arrayLength);
printf("Array Descending Order: ");
for(int i = 0; i < 8; ++i){
printf("%.1lf, ", primaryArray[i]);
}
printf("\n");
printf("\nArray Element Average: %.3lf", (arrayAverage(primaryArray, arrayLength))/8);
int ancillaryarrayLength = sizeof(ancillaryArray)/sizeof(ancillaryArray[0]);
printf("\n\nPlease Finish Ancillary Array (Max 10 Elements)\nCurrent Elements: ");
for(int i = 0; i < arrayLength; ++i) {
printf("%.1lf, ", ancillaryArray[i]);
}
printf("\nEnter Elements: ");
for (int i = 8; i < 10; ++i) {
scanf("%lf", &ancillaryArray[i]);
}
printf("\nLargest Array Element: %.1lf\n", largest(ancillaryArray, ancillaryarrayLength));
printf("Smallest Array Element: %.03lf\n", smallest(ancillaryArray, ancillaryarrayLength));
lowhighSort(ancillaryArray, ancillaryarrayLength);
printf("Array Ascending Order: ");
for(int i = 0; i < 10; ++i){
printf("%.3lf, ", ancillaryArray[i]);
}
printf("\n");
highlowSort(ancillaryArray, ancillaryarrayLength);
printf("Array Descending Order: ");
for(int i = 0; i < 10; ++i){
printf("%.3lf, ", ancillaryArray[i]);
}
printf("\n");
printf("Array Element Average: %.4lf", (arrayAverage(ancillaryArray, ancillaryarrayLength))/10);
return 0;
}
Here is the final code, it works as intended! Thank you all for your help.

How to access an array in a different function

I am writing a program to solve Sudoku puzzles in C I declared the array in main() when I try and access it in a different function the compiler gives the error I've tried using pointers to the array but nothing seems to allow me to access it
error: ‘grid’ undeclared (first use in this function) 121 |
printf("%d ", &grid[i][i]);
How can I access this array from a different function?
Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
int grid[9][9] =
{
{8,0,0,0,0,0,0,0,0},
{0,0,3,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0}
};
int LineNum = 9;
int RowAmount = 9;
for (int i = 0; i < LineNum; ++i)
{
for (int i = 0; i < RowAmount; ++i)
{
printf("%d ", &grid[i][i]);
}
printf("\n");
}
}
int find_empty_box(int sudoku)
{
for (int x = 0; x <= 9; ++x)
{
for (int y = 0; y < 9; ++y)
{
if (sudoku[&x][&y] == 0)
{
return x, y;
}
}
return NULL, NULL;
}
}
int Answer_Valid(int sudoku, int guess, int row, int col)
{
int row_values = &sudoku[&row];
for (int i = 0; i < sudoku[&row]; ++i)
{
if (guess == sudoku[&row[&i]])
{
return false;
}
}
int column_values = &sudoku[&col];
for (int t = 0; t <= 9; ++t)
{
for (int n = 0; n < &sudoku[&col]; ++n)
{
if (&guess == &sudoku[&col[&n]])
{
return false;
}
}
}
int row_start = (row / 3) * 3;
int col_start = (col / 3) * 3;
for (int x = 0; x <= row_start && row_start + 3; ++x)
{
for (int y = 0; y < col_start && col_start + 3; ++y)
{
if (sudoku[&x][&y] == guess)
{
return false;
}
return true;
}
}
}
int Solver(sudoku, guess)
{
int row, col = find_empty_box(sudoku);
if (row == NULL)
{
return true;
}
for (int i = 0; i < 1||2||3||4||5||6||7||8||9; ++i)
{
if(Answer_Valid(sudoku, guess, row, col))
{
sudoku[&row][&col] = guess;
if(Solver(sudoku))
{
return true;
}
return false;
}
}
int LineNum = 9;
int RowAmount = 9;
for (int i = 0; i < LineNum; ++i)
{
for (int i = 0; i < RowAmount; ++i)
{
printf("%d ", &grid[i][i]);
}
printf("\n");
}
}

Adding two really large numbers in C

I am trying to add two really large numbers (say 30 digit long) in C. Here is my code:
#include <stdio.h>
#include <string.h>
int main()
{
char a[30] =
{
'1','1','1','1','1','1','1','1','1','1','1','1','1','1','1',
'1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'
. };
b[30] =
{
'8','8','8','8','8','8','8','8','8','8','8','8','8','8','8',
'8','8','8','8','8','8','8','8','8','8','8','8','8','8','8'
};
int i, j, k, carry = 0, sum[1001];
if(strlen(a) >= strlen(b))
{
k = strlen(a);
}
else
{
k = strlen(b);
}
for(i = strlen(a); i > 0; i--)
{
for(j = strlen(b); j > 0; j--)
{
sum[k] = (a[i]-'0') + (b[j]-'0') + carry;
carry = sum[k]/10;
k--;
}
}
for(i = 0; i < k; i++)
{
printf("%d", sum[i]);
}
printf("\n");
return 0;
}
but it gives me no answer at all. What is wrong with it?
Small change to the code above to take care of the last trailing carry value if it > 0:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
int temp = 0;
char *fp ;
char *sp ;
char bigger = '\n';
char a[10] =
{
'1','2','3','4','5','6','7','8','9','1'
};
char b[10] =
{
'9','8','9','8','9','8','9','8','9','8'
};
int i, c, j, k, carry = 0, sum[1001] = {0};
if(sizeof(a) > sizeof(b))
{
k = sizeof(a);
j = sizeof(b);
bigger = 'a';
}
else
{
k = sizeof(b);
j = sizeof(a);
bigger = 'b';
}
c = k;
fp = malloc(k);
sp = malloc(j);
if (bigger == 'a')
{
strncpy(fp, a, k);
strncpy(sp, b, j);
}
else
{
strncpy(fp, b, k);
strncpy(sp, a, j);
}
for(i = strlen(fp); i > 0; i--,j--)
{
if(j>0 )
{
temp = *(fp+i-1)-'0' + *(sp+j-1)-'0' + carry;
if(temp < 10)
{
sum[k] += temp;
carry = 0;
}
else
{
sum[k] += temp%10;
carry = temp/10;
}
}
else
{
temp = *(fp+i-1)-'0' + carry;
if(temp < 10)
{
sum[k] += temp;
carry = 0;
}
else
{
sum[k] += temp%10;
carry = temp/10;
}
}
k--;
}
if(carry > 0)
printf("%d", carry);
for(i = 1; i <= c; i++)
{
printf("%d", sum[i]);
}
printf("\n");
return 0;
}
This should work. I changed the way your loops should work and also added some checks to ensure alignment and consistency in case the length of the large numbers change.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int temp = 0;
char *fp ;
char *sp ;
char bigger = '\n';
char a[30] =
{'1','1','1','1','1','1',
'1','1','1','1','1','1',
'1','1','1','1','1','1','1','1','1','1','1','1','1',
'1','1','1','1','1'
};
char b[30] =
{
'8','8','8','8','8','8','8','8','8','8','8','8','8','8',
'8','8','8','8','8','8','8','8','8','8','8','8','8','8',
'8','8'
};
int i, c, j, k, carry = 0, sum[1001] = {0};
if(sizeof(a) > sizeof(b))
{
k = sizeof(a);
j = sizeof(b);
bigger = 'a';
}
else
{
k = sizeof(b);
j = sizeof(a);
bigger = 'b';
}
c = k;
fp = malloc(k);
sp = malloc(j);
if (bigger == 'a')
{
strncpy(fp, a, k);
strncpy(sp, b, j);
}
else
{
strncpy(fp, b, k);
strncpy(sp, a, j);
}
for(i = strlen(fp); i > 0; i--,j--)
{
if(j>0 )
{
temp = *(fp+i-1)-'0' + *(sp+j-1)-'0' + carry;
if(temp < 10)
{
sum[k] += temp;
carry = 0;
}
else
{
sum[k] += temp%10;
carry = temp/10;
}
}
else
{
temp = *(fp+i-1)-'0' + carry;
if(temp < 10)
{
sum[k] += temp;
carry = 0;
}
else
{
sum[k] += temp%10;
carry = temp/10;
}
}
k--;
}
if(carry > 0)
printf("%d", carry);
for(i = 1; i <= c; i++)
{
printf("%d", sum[i]);
}
printf("\n");
return 0;
}

Pointers and Dynamic Memory

I have a function that returns a pointer to an array. I'm running it in a loop and free() seems to be giving me problems. I'm not sure where, but it appears that somewhere in the main loop the memory that I'm trying to free is being used. I'm using Xcode 3.2.1 in 10.6 | Debug | x86_64 build.
The program will run through the main loop one time; the second time it encounters the free() it gives me the following error:
malloc: *** error for object 0x100100180: incorrect checksum for freed object -
object was probably modified after being freed.
Can someone point out (no pun intended) what I'm doing wrong with pointers here?
Here is the program:
int main(int argc, char **argv) {
int *partition;
int lowerLimit;
int upperLimit;
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
// these loops are part of the Atkins Sieve implementation
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Why is intAlloc not returning int* ?
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if(ptr == NULL) {
printf("Error: NULL pointer\n");
exit(1);
}
return ptr; //like this
}
EDIT (after your update):
On atkinsPrimes() where is filtered being intAlloc()ed?
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int resultsSize;
primes = intAlloc(limit+1);
// ...
initialPrimes = intAlloc(2);
// ...
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered); // Where was it intAlloc()ed?
results[resultsSize] = 0; // make the array 0-terminated to make it easier to work with
return results;
}
EDIT (after your N-th update):
This is a compilable version of your code. It ran smooth on my machine, no crashes. Compiled with g++ (due to declarations of variables inside the for statement):
g++ (Debian 4.3.2-1.1) 4.3.2
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int *goldbachPartition(int x);
int *atkinsPrimes(int limit);
int trueCount(int *subject, int arraySize);
int intCount(int *subject) ;
void intFillArray(int *subject, int arraySize, int value);
int *intFilterArrayKeys(int *subject, int arraySize);
int *intAlloc(int amount);
void printOutput(int num1, int num2, int rep) ;
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2);
int main(int argc, char **argv) {
if (argc < 3) {
printf("Usage: ./program <lower> <upper>\n");
return 0;
}
int *partition;
int lowerLimit = atoi(argv[1]);
int upperLimit = atoi(argv[2]);
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Since you are still omitting some source, I can only imagine that the problem is hidden there.
EDIT: (my last update)
To assist your debugging, you should replace your main() function by the one below:
int main(int argc, char **argv)
{
int *primes = NULL;
primes = atkinsPrimes(44); // Evil magic number
free(primes);
return 0;
}
Having a minimal example to reproduce the behavior you pointed out is much better then the whole thing. Have fun with atkinsPrimes(44)

Resources