Segfault when creating an array larger than 100000 [duplicate] - c

This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 3 years ago.
How can I fix this code? I can't input a value for n more than 100000 but I have declared it as long long int.
I tried to solve it but couldn't. Please tell me what is wrong.
#include<stdio.h>
void main() {
long int n;
scanf("%ld",&n);
unsigned long long int a[n];
unsigned long long int max[n];
for(unsigned long long int i=0;i<n;i++) {
scanf("%lld",&a[i]);
}
for(unsigned long long int i=0;i<n;i++) {
unsigned long long int count=0;
for(unsigned long long int j=0;j<n;j++) {
if(a[i]==a[j]) {
count++;
}
}
max[i]=count;
}
for(unsigned long long int i=1;i<n;i++) {
if(max[0]<max[i]) {
max[0]=max[i];
a[0]=a[i];
}
else if(max[0]==max[i]) {
if(a[0]>a[i]) {
a[0]=a[i];
}
}
}
printf("%lld",a[0]);
}

You're declaring variables on the stack that are too big:
unsigned long long int a[n];
unsigned long long int max[n];
These variables are declared local to the function main, meaning that on most implementations they live on the stack. The stack is typically not that big, so when you specify a large value for n it creates arrays on the stack that are too big, overflowing the stack and causing a segfault.
Rather than creating the arrays on the stack, use malloc to create them on the heap:
unsigned long long int *a = malloc(n * sizeof(*a));
unsigned long long int *max = malloc(n * sizeof(*a));
Also, make sure you check the return value of malloc and call free when you're done.

Related

error conflicting data types [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
int main() {
long int a;
long int b;
long int c;
long int d;
long int e;
scanf("%lld %lld %lld %lld %lld",&a,&b,&c,&d,&e);
int i,j;
long int sum = 0;
long int largestsum =0;
long int smallestsum = 0 ;
long int a [5] = {a,b,c,d,e};
for ( i =0;i<5;i++){
for (j = 0;j<5;j++){
if (a[j]!=a[i]){
sum+=a[j];
}
}
if (largestsum <sum){
largestsum = sum;
}
if (smallestsum>sum){
smallestsum = sum;
}
}
printf("%ld %ld",largestsum,smallestsum);
return 0;
}
i'm trying to find the largest and the smallest sums between 5 inputs the problem is that i made the array of long ints the same as variables and i have the error conflicting data types in a which is the array what is the problem ?
What is a ?
Is it a long int as in line 2 ? long int a;
Or is it an array of long int as in line 12 long int a [5] = {a,b,c,d,e};
The compiler gets confused when he sees line 12, assumes you are doing the same thing again (which it would probably tolerate), then sees that you are using a different type (array instead of long int).
He concludes "Those are not the same types. That is a conflict of types."
Solution:
Rename a-the-array to "liArray", everywhere it is referenced.
Et voila: gcc -Wall Toy.c does not complain and running it does not crash.
Afterwards read the comments, they have more to say on how to get the program actually do what it is supposed to. Below I did only the array renaming.
#include <stdio.h>
int main()
{
long int a;
long int b;
long int c;
long int d;
long int e;
scanf("%ld %ld %ld %ld %ld",&a,&b,&c,&d,&e);
int i,j;
long int sum = 0;
long int largestsum =0;
long int smallestsum = 0 ;
long int liArray[5] = {a,b,c,d,e};
for ( i =0;i<5;i++){
for (j = 0;j<5;j++){
if (liArray[j]!=liArray[i]){
sum+=liArray[j];
}
}
if (largestsum <sum){
largestsum = sum;
}
if (smallestsum>sum){
smallestsum = sum;
}
}
printf("%ld %ld",largestsum,smallestsum);
return 0;
}

Error allocating memory of unsigned longs in C

I am writing a C program that needs to use some pretty large arrays. I allocate memory for my array by calling:
unsigned long *visited = declareArrayofLongs(my_pow(2, d));
The declareArrayofLongs() function is:
unsigned long int* declareArrayofLongs(unsigned long int length)
{
unsigned long int *myarray = (unsigned long int*) malloc(length*sizeof(unsigned long int));
if (myarray==NULL)
printf("Error allocating memory for unsigned longs!\n");
unsigned long int i;
for(i=0; i<length; i++)
myarray[i] = 0;
return myarray;
}
And my_pow() is
unsigned long int my_pow(int base, int exp)
{
unsigned long int pow=1;
int i=0;
for(i=0; i<exp; i++){
pow = (unsigned long int)base*pow;
}
return pow;
}
When the program runs and gets up to around d=29, I get "Error allocating memory for unsigned longs!". I have 16gb of RAM on my system. Shouldn't I be able to handle this amount of allocation?
Only one visited array is declared at a time. I have a free(visited) call before re-allocating.
You are not showing my_pow. Since your code doesn't work, what makes you think it does what you think it does?
You may be running 32 bit code, in which case you won't get more than about 3GB, no matter how much RAM.

I have seg fault in my counting sort

Here is my code, for some reason I have to use unsigned long. The gdb tells me that I have
seg fault. Can one can help me? I could not find it by myself. The most interesting thing is that if I change the type to int from unsigned long, there is no seg fault.
Code is here:
#include <stdio.h>
int counting_Sort (unsigned long ary[], unsigned long array_size,unsigned long max){
unsigned long counting[max+1];
unsigned long j;
for(j=0;j<max+1;j++){
counting[j]=0;//initize to zero
}
unsigned long i;
for(i=0;i<array_size;i++){
counting[ary[i]]++;
}
unsigned long q;
for(q=1;q<max+1;q++){
counting[q]=counting[q-1]+counting[q];
}
for(q=0;q<max+1;q++){
counting[q]=counting[q]-1;
}
unsigned long outputAry[array_size];
unsigned long d;
for(d=(array_size-1); d>=0;d--){
outputAry[counting[ary[d]]]=ary[d];// SEG FAULT IS HERE
counting[ary[d]]--;//AND HERE
}
unsigned long m;
//for(m=0; m<array_size;m++){
// printf("%lu\n",outputAry[m]);
// }
return 0;
}
int main(){
unsigned long array[7]={2,6,4,0,1,7,9};
printf("before sorting the order is: \n");
unsigned long i;
for(i=0;i<7;i++){
printf("%lu\n",array[i]);
}
printf("after sorting, the new order is: \n");
counting_Sort(array,7,9);
getchar();
return 0;
}
You've found the place, just not the reason.
unsigned long d;
for(d=(array_size-1); d>=0;d--){
d is an unsigned integer, which means d>=0 is always true. The loop never ends, and that's the reason of segmentation fault.
One way is to change d to a singed type:
int d;
But if that's not what you want, change the for loop to:
for (d = 0; d <= array_size - 1; d++){

C program : crashes for values greater than 0.3 million [duplicate]

This question already has answers here:
Big array gives segmentation error in C
(4 answers)
Closed 9 years ago.
This program is to find the prime number which is is the sum of most number of consecutive prime numbers. When I set the value of LIMIT to 50 100 or even 1000, the correct values are obtained. But if I take the value of LIMIT greater than 0.3 million the program crashes. What is the reason behind this problem and how can I solve it?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define LIMIT 300000
//binary search function
int Bsearch(long long int *arr,long long int low,long long int high,long long int search)
{
if(high<low)
return 0;
long long int mid = (low+high)/2;
if(search<arr[mid])
{return(Bsearch(arr,low,mid-1,search));}
else if(search>arr[mid])
{return(Bsearch(arr,mid+1,high,search));}
else if(search==arr[mid]) return 1;
else return 0;
}
int main()
{
long int arr[LIMIT];
arr[0]=0;arr[1]=1;
for(long long int i=2;i<=LIMIT;i++)
{arr[i]=1;}
long long index=2;
for(long long int i=3;i<=LIMIT;i++,index++)
{
for(long long int j=2;j<=sqrt(i);j++)
{
if(i%j==0)
{arr[index]=0;}
}
}
long long int count=0;
//calculate total primes
for(long int A=0;A<LIMIT;A++)
{
if(arr[A]==1)
count++;
}
//all primes stored in seperate primes array
long long int primes[count];
for(long int A=0,index=0;A<LIMIT;A++)
{
if(arr[A]==1)
{
primes[index++]=A+1;
}
}
long long int primes_sum[count];
primes_sum[0]=primes[0];
for(long long int B=1;B<count;B++)
{primes_sum[B]=primes_sum[B-1]+primes[B];}
for(long long int i =0;i<(sizeof(primes)/sizeof(long long int));i++)
{
printf("\nprime number : %lld\tprimes_sum : %lld",primes[i],primes_sum[i]);
}
struct ultimata
{
long long int num_of_primes;
long long int prime_number;
}final;
final.num_of_primes=0;final.prime_number=0;
for(long long int j=(sizeof(primes_sum)/sizeof(long long int))-1;j>=2;j--)
{
for(long long int i=j-2;i>=1;i--)
{
long long int search_term = primes_sum[j]-primes_sum[i];
printf("\nsearch term : %lld (primes_sum[%lld]-primes_sum[%lld])",search_term,j,i);
if(search_term>LIMIT)
break;
if(Bsearch(primes,0,(sizeof(primes)/sizeof(long long int)),search_term))
{
printf("\nfound! : %lld terms : %lld",search_term,j-i-1);
if((j-i-1)>final.num_of_primes)
{
printf("\nfound! : %lld",search_term);
final.prime_number=search_term;
final.num_of_primes=j-i-1;
}
}
}
}
printf("Largest prime number : %lld",final.prime_number,final.num_of_primes);
return 0;
}
I think one of your problems is in these lines (multiple times in other places, too):
long int arr[LIMIT];
...
for(long long int i=2;i<=LIMIT;i++)
{arr[i]=1;}
Your array has LIMIT entries, but you try to write to entry LIMIT+1. C starts with array index 0 and ends with size-1.
I don't know why it works for smaller values of LIMIT.

C - memory realloc error

I'm new to programming and here's a program that can find out all the prime numbers within a limit. However, there is an error that says:
Prime 2(1682,0x7fff76316310) malloc: *** error for object 0x1002000a0: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug'
Also, Xcode reports an issue says 'signal SIGABRT'.
I suspect that is has something to do with the function 'realloc'.
What exactly is the problem and how to fix the code?
Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
const int unit=3;
unsigned long* expandMem(unsigned long *primePtr, unsigned long count){
unsigned long* newPtr=(unsigned long*)realloc(primePtr, (count+unit)*sizeof(unsigned long));
return newPtr;
}
int main(){
unsigned long limit;
unsigned long count=0;
unsigned long* primePtr=(unsigned long*)malloc(sizeof(unsigned long)*unit);
*primePtr=2;
printf("Input the upper limit >>> ");
scanf("%ld",&limit);
for (unsigned long int number=3; number<=limit; number+=2) {
bool isPrime=true;
for (unsigned long i=0; (*(primePtr+i))*(*(primePtr+i))<=number; i++) {
if (number%(*(primePtr+i))==0) {
isPrime=false;
break;
}
}
if (isPrime) {
count++;
*(primePtr+count)=number;
if (count%unit==2) {
primePtr=expandMem(primePtr, count);
}
}
}
for (unsigned long i=0; i<=count; i++) {
printf("%ld ",*(primePtr+i));
}
}
The realloc will only allocate space for 2 new elements but you assume it allocates space for 3 new elements.
Suggested change (in expandMem):
unsigned long* newPtr=(unsigned long*)realloc(primePtr, (count+1+unit)*sizeof(unsigned long));

Resources