My program crashes if the vector is too large? - c

When I test my program with large vectors, as in larger than 12 elements, it crashes (I get an lldb error). However, it works fine for small vectors. I think it's trying to access a memory space it shouldn't, but I have no idea how to fix it.
The program is supposed to print out the vectors whose sum of elements are equal to the "target"
Also, is there a different way that I can express: if (i & (1 << j)) ?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int c = 0;
/* find subsets of a given set */
void findSubsets(int *value, int n, int i) {
int j;
if (i < 0)
return;
for (j = 0; j < n; j++) {
/*
* checking jth bit is set in i. If
* it is set, then fetch the element at
* jth index in value array
*/
if (i & (1 << j)) {
suma = suma + value[j];
}
/* recursive call */
findSubsets(value, n, i - 1);
return;
}
int main() {
/* 2^n - indicates the possible no of subsets */
int count = pow(2, size);
/* finds the subsets of the given set */
findSubsets(vector, size, count - 1);
return 0;
}
I would like to be able to use this program for large vectors (up to about 20)

The problem is that you got 52428810 recursive function calls. This will cause a stack overflow. Instead of recursion, try iteration:
for (int i = 0; i < count; i++) {
findSubsets(vector, size, i);
}
And remove the recursive call within findSubsets.

Related

Nth Fibonacci using pointers in C; recursive and array

I have this code so far. It works and does what I want it to. I'm wondering if I could make it better. I do not really care for user input or any other "finish touches," just want to make the code more efficient and maybe more useful for future projects.
Excessive comments are for my personal use, I find it easier to read when I go back to old projects for references and what not.
Thanks!
#include<stdio.h>
#include<stdlib.h>
void fabonacci(int * fibArr,int numberOfSeries){
int n;
//allocate memory size
fibArr = malloc (sizeof(int) * numberOfSeries);
//first val, fib = 0
*fibArr = 0;//100
fibArr++;
//second val, fib = 1
*fibArr = 1;//104
fibArr++;
//printing first two fib values 0 and 1
printf("%i\n%i\n", *(fibArr- 2),*(fibArr- 1));
//loop for fib arr
for(n=0;n<numberOfSeries -2;n++,fibArr++){
//108 looking back at 104 looking back at 100
//112 looking back at 108 looking back at 104
*fibArr = *(fibArr-1) + *(fibArr -2);
//printing fib arr
printf("%i\n", *fibArr);
}
}
int main(){
//can implm user input if want
int n = 10;
int *fib;
//calling
fabonacci(fib,n);
}
Your code is halfway between two possible interpretations and I can't tell which one you meant. If you want fibonacci(n) to just give the nth number and not have any external side effects, you should write it as follows:
int fibonacci(int n) {
int lo, hi;
lo = 0;
hi = 1;
while(n-- > 0) {
int tmp = hi;
lo = hi;
hi = lo + tmp;
}
return lo;
}
You need no mallocs or frees because this takes constant, stack-allocated space.
If you want, instead, to store the entire sequence in memory as you compute it, you may as well require that the memory already be allocated, because this allows the caller to control where the numbers go.
// n < 0 => undefined behavior
// not enough space allocated for (n + 1) ints in res => undefined behavior
void fibonacci(int *res, int n) {
res[0] = 0;
if(n == 0) { return; }
res[1] = 1;
if(n == 1) { return; }
for(int i = 2; i <= n; i++) {
res[i] = res[i-1] + res[i-2];
}
}
It is now the caller's job to allocate memory:
int main(){
int fib[10]; // room for F_0 to F_9
fibonacci(fib, 9); // fill up to F_9
int n = ...; // some unknown number
int *fib2 = malloc(sizeof(int) * (n + 2)); // room for (n + 2) values
if(fib2 == NULL) { /* error handling */ }
fibonacci(fib2 + 1, n); // leave 1 space at the start for other purposes.
// e.g. you may want to store the length into the first element
fib2[0] = n + 1;
// this fibonacci is more flexible than before
// remember to free it
free(fib2);
}
And you can wrap this to allocate space itself while still leaving the more flexible version around:
int *fibonacci_alloc(int n) {
int *fib = malloc(sizeof(int) * (n + 1));
if(fib == NULL) { return NULL; }
fibonacci(fib, n);
return fib;
}
One way to improve the code is to let the caller create the array, and pass the array to the fibonacci function. That eliminates the need for fibonacci to allocate memory. Note that the caller can allocate/free if desired, or the caller can just declare an array.
The other improvement is to use array notation inside of the fibonacci function. You may be thinking that the pointer solution has better performance. It doesn't matter. The maximum value for n is 47 before you overflow a 32-bit int, so n is not nearly big enough for performance to be a consideration.
Finally, the fibonacci function should protect itself from bad values of n. For example, if n is 1, then the function should put a 0 in the first array entry, and not touch any other entries.
#include <stdio.h>
void fibonacci(int *array, int length)
{
if (length > 0)
array[0] = 0;
if (length > 1)
array[1] = 1;
for (int i = 2; i < length; i++)
array[i] = array[i-1] + array[i-2];
}
int main(void)
{
int fib[47];
int n = sizeof(fib) / sizeof(fib[0]);
fibonacci(fib, n);
for (int i = 0; i < n; i++)
printf("fib[%d] = %d\n", i, fib[i]);
}

What is wrong with my hash function?

I'm trying to create a hash table. Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define N 19
#define c1 3
#define c2 5
#define m 3000
int efort;
int h_table[N];
int h(int k, int i)
{
return (k + i*c1 + i*i*c2) % N;
}
void init()
{
for (int i = 0; i < N; i++)
h_table[i] = -1;
}
void insert(int k)
{
int position, i;
i = 0;
do
{
position = h(k, i);
printf("\n Position %d \n", position);
if (h_table[position] == -1)
{
h_table[position] = k;
printf("Inserted :elem %d at %d \n", h_table[position], position);
break;
}
else
{
i += 1;
}
} while (i != N);
}
void print(int n)
{
printf("\nTable content: \n");
for (int i = 0; i < n; i++)
{
printf("%d ", h_table[i]);
}
}
void test()
{
int a[100];
int b[100];
init();
memset(b, -1, 100);
srand(time(NULL));
for (int i = 0; i < N; i++)
{
a[i] = rand() % (3000 + 1 - 2000) + 2000;
}
for (int i = 0; i < N ; i++)
{
insert(a[i]);
}
print(N);
}
int main()
{
test();
return 0;
}
Hash ("h") function and "insert" function are took from "Introduction to algorithms" book (Cormen).I don't know what is happening with the h function or insert function. Sometimes it fills completely my array, but sometimes it doesn't. That means it doesn't work good. What am I doing wrong?
In short, you are producing repeating values for position often enough to prevent h_table[] from being populated after only N attempts...
The pseudo-random number generator is not guaranteed to produce a set of unique numbers, nor is your h(...) function guaranteed to produce a mutually exclusive set of position values. It is likely that you are generating the same position enough times that you run out of loops before all 19 positions have been generated. The question how many times must h(...) be called on average before you are likely to get the value of an unused position? should be answered. This may help to direct you to the problem.
As an experiment, I increased the looping indexes from N to 100 in all but the h(...) function (so as not to overrun h_table[] ). And as expected the first 5 positions filled immediately. The next one filled after 3 more tries. The next one 10 tries later, and so on, until by the end of 100 tries, there were still some unwritten positions.
On the next run, all table positions were filled.
2 possible solutions:
1) Modify hash to improve probability of unique values.
2) Increase iterations to populate h_table
A good_hash_function() % N may repeat itself in N re-hashes. A good hash looks nearly random in its output even though it is deterministic. So in N tries it might not loop through all the array elements.
After failing to find a free array element after a number of tries, say N/3 tries, recommend a different approach. Just look for the next free element.

exceeding 500000 with the method of Erastosthenes

i got a problem which i can't solve
I want to know all prime numbers below a given limit x. Allowing me to enter x and calculate the prime numbers using the method of Erastosthenes. Displaying the result on the screen and saving it to a text file.
Calculating the primenumbers below the x, printing them and saving them to a text file worked, the only problem i have is that x can't exceed 500000
could you guys help me?
#include <stdio.h>
#include <math.h>
void sieve(long x, int primes[]);
main()
{
long i;
long x=500000;
int v[x];
printf("give a x\n");
scanf("%d",&x);
FILE *fp;
fp = fopen("primes.txt", "w");
sieve(x, v);
for (i=0;i<x;i++)
{
if (v[i] == 1)
{
printf("\n%d",i);
fprintf(fp, "%d\n",i);
}
}
fclose(fp);
}
void sieve(long x, int primes[])
{
int i;
int j;
for (i=0;i<x;i++)
{
primes[i]=1; // we initialize the sieve list to all 1's (True)
primes[0]=0,primes[1]=0; // Set the first two numbers (0 and 1) to 0 (False)
}
for (i=2;i<sqrt(x);i++) // loop through all the numbers up to the sqrt(n)
{
for (j=i*i;j<x;j+=i) // mark off each factor of i by setting it to 0 (False)
{
primes[j] = 0;
}
}
}
You will be able to handle four times as many values by declaring char v [500000] instead of int v [100000].
You can handle eight times more values by declaring unsigned char v [500000] and using only a single bit for each prime number. This makes the code a bit more complicated.
You can handle twice as many values by having a sieve for odd numbers only. Since 2 is the only even prime number, there is no point keeping them in the sieve.
Since memory for local variables in a function is often quite limited, you can handle many more values by using a static array.
Allocating v as an array of int is wasteful, and making it a local array is risky, stack space being limited. If the array becomes large enough to exceed available stack space, the program will invoke undefined behaviour and likely crash.
While there are ways to improve the efficiency of the sieve by changing the sieve array to an array of bits containing only odd numbers or fewer numbers (6n-1 and 6n+1 is a good trick), you can still improve the efficiency of your simplistic approach by a factor of 10 with easy changes:
fix primes[0] and primes[1] outside the loop,
clear even offsets of prime except the first and only scan odd numbers,
use integer arithmetic for the outer loop limit,
ignore numbers that are already known to be composite,
only check off odd multiples of i.
Here is an improved version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sieve(long x, unsigned char primes[]) {
long i, j;
for (i = 0; i < x; i++) {
primes[i] = i & 1;
}
primes[1] = 0;
primes[2] = 1;
/* loop through all odd numbers up to the sqrt(x) */
for (i = 3; (j = i * i) < x; i += 2) {
/* skip composite numbers */
if (primes[i] == 0)
continue;
/* mark each odd multiple of i as composite */
for (; j < x; j += i + i) {
primes[j] = 0;
}
}
}
int main(int argc, char *argv[]) {
long i, x, count;
int do_count = 0;
unsigned char *v;
if (argc > 1) {
x = strtol(argv[1], NULL, 0);
} else {
printf("enter x: ");
if (scanf("%ld", &x) != 1)
return 1;
}
if (x < 0) {
x = -x;
do_count = 1;
}
v = malloc(x);
if (v == NULL) {
printf("Not enough memory\n");
return 1;
}
sieve(x, v);
if (do_count) {
for (count = i = 0; i < x; i++) {
count += v[i];
}
printf("%ld\n", count);
} else {
for (i = 0; i < x; i++) {
if (v[i] == 1) {
printf("%ld\n", i);
}
}
}
free(v);
return 0;
}
I believe the problem you are having is allocating an array of int if more than 500000 elements on the stack. This is not an efficient way, to use an array where the element is the number and the value indicates whether it is prime or not. If you want to do this, at least use bool, not int as this should only be 1 byte, not 4.
Also notice this
for (i=0;i<x;i++)
{
primes[i]=1; // we initialize the sieve list to all 1's (True)
primes[0]=0,primes[1]=0; // Set the first two numbers (0 and 1) to 0 (False)
}
You are reassigning the first two elements in each loop. Take it out of the loop.
You are initializing x to be 500000, then creating an array with x elements, thus it will have 500000 elements. You are then reading in x. The array will not change size when the value of x changes - it is fixed at 500000 elements, the value of x when you created the array. You want something like this:
long x=500000;
printf("give a x\n");
scanf("%d",&x);
int *v = new int[x];
This fixes your fixed size array issue, and also gets it off the stack and into the heap which will allow you to allocate more space. It should work up to the limit of the memory you have available.

Segmentation Fault 11 with recursive function in C

I keep receiving a Segmentation Fault 11 for the following code. I believe it has something to do with recursion but I'm not entirely sure how. The method should take in an array, skip the odd values, and keep repeating until it has an array with only value left and returns that value.
Thanks!
#include <stdio.h>
int callTable(int table[], int size)
{
int i = 0;
int j = 0;
int cHeight = size / 2;
int cTable[cHeight];
while (i < size)
{
if (table[i] % 2 == 0)
{
cTable[j] = table[i];
j++;
}
i++;
}
if (size > 1)
return callTable(cTable, cHeight);
else
return cTable[0];
}
int main()
{
int tPass[100];
int i, answer;
for (i = 0; i < 100; i++)
tPass[i] = i + 1;
answer = callTable(tPass, sizeof(tPass) / sizeof(tPass[0]));
printf("%d\n", answer);
}
Do you want to skip the odd values or the odd indexes? You are currently skipping the odd values, so after you call callTable once, there are only even values left. Then, on the second call, you try to use an array of half the size to store the even values (which are all of them), so you try to store the entire array on another with half the size.
If you intended to skip the odd indexes, then change this line:
if (table[i]%2==0)
for this one:
if (i%2==0)
That runs fine and returns 1 (which is the number with index 0).

Segmentation fault for prime generator

I am working on a small piece of code that generates all the primes between two numbers for a set. I decided to use a sieve (and i know theres probably a much more efficient way to do what I want than the way my code is using it) and for some reason I am getting a SIGSEGV (segmentation fault). I have looked over it quite a bit and I don't know what's wrong. I haven't been able to reproduce the error on my local machine. I get this error generally occurs when accessing out of bounds, but I don't know if thats the case here. Be Gentle, I am pretty new to C, always stuck to the higher level stuff.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char argv){
int numberOfSets;
scanf("%d", &numberOfSets);
int i;
int lowerBound, upperBound;
for(i=0; i < numberOfSets; i++){
scanf("%d %d", &lowerBound, &upperBound);
//allocating memory and initializing to Zero
int (*sieve) = malloc(sizeof(int) * (upperBound+1));
memset(sieve, 0, (sizeof(int) * (upperBound+1)));
//iterating through sieve for even numbers and marking them as non prime
int counter = 2;
if(sieve[counter] == 0)
sieve[counter] = 1;
int multiplier = 2;
int multiple = counter * multiplier;
while(multiple <= upperBound){
sieve[multiple] = -1;
multiplier++;
multiple = multiplier * counter;
}
//iterating through sieve (incrementing by two) and filling in primes up to upper limit
counter = 3;
while( counter <= upperBound){
if(sieve[counter] == 0)
sieve[counter] = 1;
multiplier = 2;
multiple = counter * multiplier;
while(multiple < upperBound){
sieve[multiple] = -1;
multiplier++;
multiple = multiplier * counter;
}
counter = counter + 2;
}
int newCount = lowerBound;
//check and print which numbers in the range are prime
while (newCount <= upperBound){
if(sieve[newCount] == 1)
printf("%d\n", newCount);
newCount=newCount+1;
}
//free the allocated memort
free(sieve);
}
}
The problem was that I was not checking the result of Malloc. I was attempting to allocate an array that was to large and the allocation was failing. This left the array I was assigning to null and thus I was accessing out of its bounds.

Resources