I am trying to sort an array of structures of size 5500 using merge sort.
However, I am getting a segmentation fault pretty quickly because I am not allowed to use VLA. so I have to create 2 extra arrays of size 5500 each time I call merge-sort recursively.
I would appreciate a fix for my problem. I will provide my code here:
void merge(Student rightArr[], Student leftArr[], Student mergedArr[], int sizeOfRight, int sizeOfLeft) {
int rightArrIndex = 0;
int leftArrIndex = 0;
int mergedArrIndex = 0;
while (leftArrIndex < sizeOfLeft && rightArrIndex < sizeOfRight) {
char *ptrLeft, *ptrRight;
long gradeLeft = strtol(leftArr[leftArrIndex].grade, &ptrLeft, BASE_COUNT);
long gradeRight = strtol(rightArr[rightArrIndex].grade, &ptrRight, BASE_COUNT);
if (gradeLeft > gradeRight) {
mergedArr[mergedArrIndex] = rightArr[rightArrIndex];
rightArrIndex++;
} else {
mergedArr[mergedArrIndex] = leftArr[leftArrIndex];
leftArrIndex++;
}
mergedArrIndex++;
}
if (leftArrIndex == sizeOfLeft) {
for (int i = mergedArrIndex; i < (sizeOfLeft + sizeOfRight); i++) {
mergedArr[i] = rightArr[rightArrIndex];
rightArr++;
}
} else {
for (int i = mergedArrIndex; i < (sizeOfLeft + sizeOfRight); i++) {
mergedArr[i] = leftArr[leftArrIndex];
leftArr++;
}
}
}
void mergeSort(Student studentsArray[], int amountOfStudents) {
if (amountOfStudents <= 1) {
return;
}
int leftSize = (amountOfStudents / 2);
int rightSize = (amountOfStudents - leftSize);
Student leftArr[5500], rightArr[5500];
for (int i = 0; i < leftSize; i++) {
leftArr[i] = studentsArray[i];
}
for (int i = 0; i < rightSize; i++) {
rightArr[i] = studentsArray[i + leftSize];
}
mergeSort(leftArr, leftSize);
mergeSort(rightArr, rightSize);
merge(rightArr, leftArr, studentsArray, rightSize, leftSize);
}
Ok, I think this should do what you want. It assumes that Student and BASE_COUNT have been defined:
#include <stdlib.h>
#include <stdio.h>
void merge(Student studentsArr[],
int leftSize, int rightSize,
Student scratchArr[])
{
Student *leftArr = studentsArr;
Student *rightArr = studentsArr + leftSize;
int leftIx = 0, rightIx = 0, mergeIx = 0, ix;
while (leftIx < leftSize && rightIx < rightSize) {
long gradeLeft = strtol(leftArr[leftIx].grade, NULL, BASE_COUNT);
long gradeRight = strtol(rightArr[rightIx].grade, NULL, BASE_COUNT);
if (gradeLeft <= gradeRight) {
scratchArr[mergeIx++] = leftArr[leftIx++];
}
else {
scratchArr[mergeIx++] = rightArr[rightIx++];
}
}
while (leftIx < leftSize) {
scratchArr[mergeIx++] = leftArr[leftIx++];
}
// Copy the merged values from scratchArr back to studentsArr.
// The remaining values from rightArr (if any) are already in
// their proper place at the end of studentsArr, so we stop
// copying when we reach that point.
for (ix = 0; ix < mergeIx; ix++) {
studentsArr[ix] = scratchArr[ix];
}
}
void mergeSortInternal(Student studentsArray[],
int amountOfStudents,
Student scratchArr[])
{
if (amountOfStudents <= 1) {
return;
}
int leftSize = amountOfStudents / 2;
int rightSize = amountOfStudents - leftSize;
mergeSortInternal(studentsArray, leftSize, scratchArr);
mergeSortInternal(studentsArray + leftSize, rightSize, scratchArr);
merge(studentsArray, leftSize, rightSize, scratchArr);
}
#define MAX_ARR_SIZE 5500
void mergeSort(Student studentsArray[], int amountOfStudents)
{
if (amountOfStudents <= 1) {
return;
}
if (amountOfStudents > MAX_ARR_SIZE) {
fprintf(stderr, "Array too large to sort.\n");
return;
}
Student scratchArr[MAX_ARR_SIZE];
mergeSortInternal(studentsArray, amountOfStudents, scratchArr);
}
The top-level sort function is mergeSort, defined as in the original post. It declares a single scratch array of size MAX_ARR_SIZE, defined as 5500. The top-level function is not itself recursive, so this scratch array is only allocated once.
Related
I haven't written any C for more than a decade, but here I am...
I want to be able to create and access the following items of a data structure:
FilterCoefficients[0].TargetSampleNum = 0;
FilterCoefficients[0].SourceWeights[0].Weight = 0.812;
FilterCoefficients[0].SourceWeights[0].SourceSampleNum = 0;
FilterCoefficients[0].SourceWeights[1].Weight = 0.153;
FilterCoefficients[0].SourceWeights[1].SourceSampleNum = 1;
FilterCoefficients[1].TargetSampleNum = 1;
FilterCoefficients[1].SourceWeights[0].Weight = 0.352;
FilterCoefficients[1].SourceWeights[0].SourceSampleNum = 0;
FilterCoefficients[1].SourceWeights[1].Weight = 0.721;
FilterCoefficients[1].SourceWeights[1].SourceSampleNum = 1;
[...]
The indices have to be dynamically allocated (amount of needed space changes during runtime). I am attempting to create said data structure with the following:
typedef struct SampleWeight_t
{
unsigned long SourceSampleNum;
double Weight;
} SampleWeight;
typedef struct FilterCoefficients_t
{
unsigned long TargetSampleNum;
SampleWeight* SourceWeights;
} FilterCoefficients;
However, I am having difficulties creating the structure. I am getting Break Point exceptions when malloc-ing or free-ing the structure.
FilterCoefficients* FilterCoefficients;
SampleWeight* SampleWeight;
FilterCoefficients = malloc(sizeof(FilterCoefficients) * target_width);
if (FilterCoefficients == NULL) {
//errhandler
}
for (int i = 0; i < target_width; i++) {
FilterCoefficients[i].SourceWeights = malloc(sizeof(SampleWeight) * (int)ceil(scalingFactorWidth * window_width)); // **exception usually here**
if (FilterCoefficients[i].SourceWeights == NULL) {
//errhandler
}
FilterCoefficients[i].TargetSampleNum = i;
for (int j = i - filter_width; j < i + filter_width; j++) {
FilterCoefficients[i].SourceWeights[j + filter_width].Weight = bilinear_filter(0.5 + scalingFactorWidth2 * (j - 0.5));
if (j > 0) {
FilterCoefficients[i].SourceWeights[j + filter_width].SourceSampleNum = j;
}
else {
FilterCoefficients[i].SourceWeights[j + filter_width].SourceSampleNum = 0;
}
}
}
for (int i = 0; i < target_width; i++) {
free(FilterCoefficients[i].SourceWeights); // **exception usually here**
}
free(FilterCoefficients);
Any help which is gonna point me to a solution is appreciated.
This compiles and executes. I had to simplify.
#include <stdio.h>
#include <stdlib.h>
typedef struct SampleWeight_t
{
unsigned long SourceSampleNum;
double Weight;
} SampleWeight;
typedef struct FilterCoefficients_t
{
unsigned long TargetSampleNum;
SampleWeight* SourceWeights;
} FilterCoefficients;
int main ( void) {
FilterCoefficients* FilterCoeff;
int window_width = 35;
int target_width = 55;
FilterCoeff = malloc(sizeof(FilterCoefficients) * target_width);
if (FilterCoeff == NULL) {
//errhandler
}
for (int i = 0; i < target_width; i++) {
FilterCoeff[i].SourceWeights = malloc(sizeof(SampleWeight) * window_width);
if (FilterCoeff[i].SourceWeights == NULL) {
//errhandler
}
FilterCoeff[i].TargetSampleNum = i;
for (int j = 0; j < window_width; j++) {
FilterCoeff[i].SourceWeights[j].Weight = i * j;
if (j > 0) {
FilterCoeff[i].SourceWeights[j].SourceSampleNum = j;
}
else {
FilterCoeff[i].SourceWeights[j].SourceSampleNum = 0;
}
}
}
for (int i = 0; i < target_width; i++) {
free(FilterCoeff[i].SourceWeights); // **exception usually here**
}
free(FilterCoeff);
}
I want to print all possible paths from a given source and destination. But in my BFS code, it only shows the two paths, not the multiple path. For a directed graph where n = 4, edge = 6, given,
1-2
1-3
1-5
5-3
5-4
3-4
3-2
It should've printed 3 paths:
1-5-4
1-3-4
1-5-3-4
But it only shows this two paths
1-3-4
1-5-4
This is my sample code for finding the src to destination path
#include <stdio.h>
int queue1[100], state[100], parent[100];
int front = 0, rear = -1, maxSize = 100;
int count = 0;
int initial = 1, waiting = 2, visited = 3;
int n, e;
int adj[100][100];
bool isEmpty()
{
return count == 0;
}
bool isFull()
{
return count == maxSize;
}
void enqueue(int val)
{
if (!isFull())
{
if (rear == maxSize - 1)
{
rear = -1;
}
rear++;
queue1[rear] = val;
count++;
}
}
int dequeue()
{
int val = queue1[front];
front++;
if (front == maxSize)
{
front = 0;
}
count--;
return val;
}
void BFS_Traversal(int src, int des)
{
int done = 0;
enqueue(src);
state[src] = waiting;
parent[src] = -1;
printf("path ");
while (!isEmpty() && done == 0)
{
src = dequeue();
// printf("%d ",src);
state[src] = visited;
for (int i = 1; i <= n; i++)
{
if (adj[src][i] == 1 && state[i] == initial)
{
enqueue(i);
state[i] = waiting;
parent[i] = src;
if (i == des)
{
state[i] = initial;
int k = des;
do
{
printf("%d ", k);
k = parent[k];
} while (k != -1);
printf("\n");
}
}
}
}
}
int main()
{
int src, start, end, des;
scanf("%d%d", &n, &e);
for (int i = 1; i <= e; i++)
{
scanf("%d%d", &start, &end);
adj[start][end] = 1;
}
for (int i = 1; i <= n; i++)
{
state[i] = initial;
}
for (int k = 1; k <= n; k++)
{
parent[k] = -1;
}
scanf("%d%d", &src, &des);
BFS_Traversal(src, des);
}
As, you can see 1-5-3-4 path is not showing because they are already visited. How should I modify this code to print all possible paths?
all mighty community of CS50ers on StackOverflow!
I have coded the sort and search functions of pset3, find, but I just don't get why I get this message. It is as if in the while loop the first if were never executed.
Any hints?
#include <cs50.h>
bool search(int value, int values[], int n)
{
if (n < 1)
{
return false;
}
else
{
int start = 0, end = (n-1);
while (end >= start)
{
int median = (end - start) / 2;
if (median == value)
{
return true;
}
else if (values[median] < value)
{
start = values[median + 1];
}
else
{
end = values[median - 1];
}
}
return false;
}
}
void sort(int values[], int n)
{
int temp;
for (int i = 0; i < n; i++)
{
int smallest_index = i;
for (int j = i + 1; j < n; j++)
{
if (values[i] > values[j])
smallest_index = j;
}
temp = values[smallest_index];
values[smallest_index] = values[i];
values[i] = temp;
}
}
Click Here to See Error Message from Check50
I'm fairly new to programming and i'm having problem with pointers. My code below works with the exception for that my counts doesn't follow with my article number when i sort it. I probably need pointers to get this working but I don't know how.
Can anyone help me?
void printMenu(void)
{
printf("\nMENU:\n");
printf("(D)isplay the menu\n");
printf("(G)enerate inventory\n");
printf("(P)rint inventory\n");
printf("(L)inear search article\n");
printf("(B)inary search article\n");
printf("(I)nsertion sort inventory\n");
printf("B(u)bble sort inventory\n");
printf("(M)erge sort inventory\n");
printf("(Q)uit program\n");
}
void generateInventory(article inventory[], int noOfArticles,
int minArticleNumber, int maxArticleNumber, int maxNoOfArticles)
{
int i, j;
int idCount[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
for (i = 0; i < noOfArticles; i++)
{
inventory[i].id = rand() % (maxArticleNumber - minArticleNumber + 1) +
minArticleNumber;
idCount[inventory[i].id - 1] = idCount[inventory[i].id - 1] + 1;
for (j = 0; j <= i; ++j)
{
if (idCount[inventory[i].id - 1] > 1)
{
inventory[i].id = rand() % (maxArticleNumber + minArticleNumber);
}
}
inventory[i].counts = rand() % maxNoOfArticles;
}
}
void printInventory(const article inventory[], int noOfArticles)
{
int i;
printf("\nINVENTORY\n");
printf("%7s %8s\n", "Article", "Count");
for (i = 0; i < noOfArticles; i++)
{
printf("%7d %8d\n", inventory[i].id, inventory[i].counts);
}
}
int getArticleId()
{
int id;
printf("\nGive article id: ");
scanf("%d", &id);
return id;
}
void printSearchResult(const article inventory[], int index)
{
if (index == -1)
{
printf("\nArticle not found\n");
}
else
{
printf("\nArticle id: %d\n", inventory[index].id);
printf("Article counts: %d\n", inventory[index].counts);
}
}
int linearSearchInventory(const article inventory[], int noOfArticles, int id)
{
int i = 0;
int index = -1;
while (index == -1 && i < noOfArticles)
{
if (id == inventory[i].id)
{
index = i;
}
i++;
}
}
int binarySearchInventory(const article inventory[], int noOfArticles, int id)
{
int index = -1;
int left = 0;
int right = noOfArticles - 1;
int middle;
while (index == -1 && left <= right)
{
middle = (left + right) / 2;
if (id == inventory[middle].id)
{
index = middle;
}
else if (id < inventory[middle].id)
{
right = middle - 1;
}
else
{
left = middle + 1;
}
}
return index;
}
void insertionSortInventory(article inventory[], int noOfArticles)
{
int i, j;
int next;
for (i = 1; i < noOfArticles; i++)
{
next = inventory[i].id;
j = i - 1;
while (j >= 0 && next < inventory[j].id)
{
inventory[j + 1].id = inventory[j].id;
j = j - 1;
}
inventory[j + 1].id = next;
}
}
void bubbleSortInventory(article inventory[], int noOfArticles)
{
int c, d, t;
for (c = 0; c < (noOfArticles - 1); c++)
{
for (d = 0; d < noOfArticles - c - 1; d++)
{
if (inventory[d].id > inventory[d + 1].id)
{
t = inventory[d].id;
inventory[d].id = inventory[d + 1].id;
inventory[d + 1].id = t;
}
}
}
}
void mergeSortInventory(article inventory[], int noOfArticles)
{
int temp[noOfArticles / 2];
int nLeft, nRight;
int i, iLeft, iRight;
if (noOfArticles > 1)
{
nLeft = noOfArticles / 2;
nRight = (int) ceil((double) noOfArticles / 2);
mergeSortInventory(inventory, nLeft);
mergeSortInventory(&inventory[noOfArticles / 2], nRight);
for (i = 0; i < nLeft; i++)
{
temp[i] = inventory[i].id;
}
i = 0;
iLeft = 0;
iRight = 0;
while (iLeft < nLeft && iRight < nRight)
{
if (temp[iLeft] < inventory[noOfArticles / 2 + iRight].id)
{
inventory[i].id = temp[iLeft];
iLeft = iLeft + 1;
}
else
{
inventory[i].id = inventory[noOfArticles / 2 + iRight].id;
iRight = iRight + 1;
}
i = i + 1;
}
while (iLeft < nLeft)
{
inventory[i].id = temp[iLeft];
i = i + 1;
iLeft = iLeft + 1;
}
}
}
If I'm correct in what you're asking, you want to keep the idCount array relational to the inventory array. I assume, since you're using article as a type that you've either typedef'd a variable to be an article, which would be pointless, or more likely you've built a struct of type article, then made an array of those structs, and called the array inventory.
If this is the case, then the most likely method of keeping them relational is to just include the count in the article struct.
There are methods of making the arrays relational without doing that, but they're pointless, because a simple four-line struct would do the trick, even if that struct was a wrapper around a different struct, or a header for another struct.
When sorting your records, you only assign the id member of your struct:
inventory[foo].id = inventory[bar].id;
You should assign the complete struct:
inventory[foo] = inventory[bar];
Just remember that temporaries must be of type article an not int so they allso can be assigne a complete struct and not only an id value
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)