I have seg fault in my counting sort - c

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++){

Related

Segfault when creating an array larger than 100000 [duplicate]

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.

SPOJ AGS runtime error

I was practising dynamic programming on SPOJ. I am stuck on this problem named AGS. Below is my code. It is giving runtime error on SPOJ but is running perfectly fine on my computer. Please help
#include<stdio.h>
long long mypow(long long base,long long exp,long long mod,long long log[])
{
if(log[exp]!=0)
return log[exp];
if(exp==0)
return 1;
if(exp==1)
return base%mod;
long long ans = ((base%mod) * mypow(base,exp-1,mod,log))%mod;
log[exp]=ans;
return ans;
}
long long gpsum(long long r,long long k,long long mod,long long log[])
{
if(k==0)
return 1;
if(k==1)
return 1+r;
long long ans=(mypow(r,k,mod,log)+gpsum(r,k-1,mod,log))%mod;
return ans;
}
int main()
{
long long i,t,k,a,d,r,n,mod,p,q,ans;
scanf("%lld",&t);
while(t--)
{
scanf("%lld %lld %lld",&a,&d,&r);
scanf("%lld %lld",&n,&mod);
long long log[n/2];
for(i=0;i<n/2;i++)
log[i]=0;
if(n==1)
{
ans=a;
}
else if(n%2==0)
{
k=(n-2)/2;
p=mypow(r,k,mod,log);
q=gpsum(r,k,mod,log);
ans=(((p%mod)*(a%mod))%mod+((q%mod)*(d%mod))%mod)%mod;
}
else
{
k=(n-3)/2;
p=r*mypow(r,k,mod,log);
q=r*gpsum(r,k,mod,log);
ans=(((p%mod)*(a%mod))%mod+((q%mod)*(d%mod))%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
It looks like the line long long log[n/2]; causing the error. For n = 12345678 (from the sample input in the comments) it will try to allocate around 6M of long long which is about 50Mb on the stack. Which is, I am guessing, too big for the online multi user compilers. The following code will prove this claim:
#include<stdio.h>
#define MAX 7000000
int main()
{
volatile long long v[MAX];
long i;
for ( i=0; i<MAX; i++ )
v[i]=i+1;
printf("Hello");
return 0;
}
The value of MAX as stated will give the error on ideone. Reducing the value, say to 700000 will remove the error (don't mind the volatile and the loop exercises, they are there to trick on optimizer).
A possible solution would be allocating this memory statically, as a global variable - outside the main function, such that it will go to the .data section, and not to the stack. This solution:
#include<stdio.h>
#define MAX 7000000
volatile long long v[MAX];
int main()
{
long i;
for ( i=0; i<MAX; i++ )
v[i]=i+1;
printf("Hello");
return 0;
}
works just fine even with larger numbers.

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.

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));

How to extract a number/byte from an array in C?

Here i have written a code which produces next 8 numbers from sequence.
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
I want to know how can i extract each byte/number of the array and return each number/byte ??Please help me out.
EDIT:Here's my code.Basically i want to read a file and compare the contents to check if the data read matches with generated sequential data.Here the buffer contains same data as temp_data is producing(ie 10 numbers like 0x07060504030201 next 0f0e0d0c0b0a0908 etc).I want to comapre buffer's data and the function's data.Can anyone suggest me how can i do.I am stuck.Any changes are appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<inttypes.h>
int main(void){
FILE *fp;
char *buffer,c;
size_t filesize,buffer_size;
int i;
unsigned long long int expected_data=1976943448883713;
fp=fopen("seqdata.c","r");
if(fp==NULL){
fputs("Error\n",stderr);
exit(1);
}
fseek(fp,0L,SEEK_END);
filesize=ftell(fp);
printf("Size of seqdata file is:%u \n",filesize);
fseek(fp,0L,SEEK_SET);
buffer=(char*)malloc(sizeof(char)*filesize);
if(buffer == NULL){
fputs("\nMemory error ",stderr);
}
buffer_size=fread(buffer,sizeof(char),filesize,fp);
for(i=0;i<buffer_size;i++){
printf("%c",*(buffer +i));
}
printf("No of elements read from file are:%u \n",buffer_size);
fseek(fp,0L,SEEK_SET);
int current_pos = 0;
while(current_pos < buffer_size){
if(*(buffer +current_pos) != expected_data)
{
fputs("Error\n",stderr);
exit(1);
}
else{
printf("data matching \n");
current_pos++;
expected_data=next_exp_data(expected_data);
}
}
fclose(fp);
free(buffer);
return 0;
}
int next_exp_data(unsigned long long int expected_data)
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
unsigned long long int temp_data[10];
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
It's machine dependent, but this usually works one of two ways:
union {
unsigned char b [8];
long long i;
} v;
v .i = seq_gen_value;
for (int j = 0; j < 8; ++j)
printf ("%d, ", v .b [j]);
On a little endian machine (x86, vax, etc.) the bytes come out with the least significant first. On a big endian machine, they come out with the most significant first.
By the way, it would be more useful to encode the "magic numbers" so that they can be more easily understood what they mean. For example, instead of 1976943448883713, write it as 0x7060504030201.
I think that your function do something like
return 1976943448883713 + 8 * 2260630401189896
And I think your question is not clear enough, like what array you want to return each its number? If you want to return array temp_data, it very easy. You can do that by
int next_exp_data(unsigned long long int expected_data, unsigned long long int temp_data[])
{
int i=0;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return (expected_data);
}
Call this function with the second params is a array int with size 10.
And another thing, I don't think that this function need the 1st param, because it's not be used within the function, so you can remove that from functions params list
int next_exp_data( unsigned long long int temp_data[])
{
int i=0;
unsigned long long int expected_data;
unsigned long long int seq_gen_value=1976943448883713;
temp_data[0]=seq_gen_value;
for(i=0;i<10;i++)
{
printf("%llu",temp_data[i]);
putchar('\n');
expected_data=temp_data[i];
temp_data[i+1]=temp_data[i] +2260630401189896;
}
return expected_data; //dont use (expected_data), it will make things slower.
}
Comparing numbers in C is done using ==, !=, <= , >= , <, or >.
I didn't read your code as it's horrible formatted and doesn't seem relevant to your question as posed in the title.

Resources