#include<stdio.h>
int main()
{
int t;
scanf("%d",&t);
while(t-->0)
{
long int size;
scanf("%ld",&size);
long int size2=size*size;
long int a[size],b[size2];
long int i=0;
for(i=0;i<size;i++)
{
scanf("%ld",&a[i]);
}
long int j=0;
long int y;
y=2*a[0];
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
if(i!=0 && j!=0)
{
b[i*size+j]=a[i]+a[j];
y=y^b[i*size+j];
}
}
}
printf("%ld\n",y);
}
}
I was solving for one of the problems on a popular Competitive Coding Websites, I wrote this code it works for most test cases I tried but, they didn't consider it as it gave them an RE(SIGSEV)->(Runtime error due to segmentation fault.), And didn't even provide with the test case where the error sneaked in,
I made sure about the semantics of taking Input for data variables of different types and (Even made sure my code stays within the allowed limit of 50000 bytes.) Can somebody help me understand what is causing the segmentation fault here?
This segmentation fault is caused by allocating too much automatic memory through VLA (variable-length arrays).
I made sure my code stays within the allowed limit of 50000 bytes
Large VLAs may cause undefined behavior even if your program has plenty of memory available for dynamic allocation, because they take memory from the automatic storage (commonly referred to as "stack"). The amount of automatic storage available to your program is usually a fraction of the total memory available to your process.
You can fix this problem by switching to dynamic allocation:
long int *a = malloc(sizeof(long int)*size);
long int *b = malloc(sizeof(long int)*size2);
...
free(a);
free(b);
Related
I am testing the sorting techniques (Mergesort, Quicksort,...so on) in 'C' experimentally for comparison of time. For this purpose, I am generating an array of large sizes up to 10^8 randomly as shown in the code below. But this piece of code is working for the generation of size up to 10^5. If this limit exceeds the compiler stops working and displays a dialogue box "a.exe has stopped working".
Please help me out with this problem.
Thanks
int main(){
srand(time(NULL));
long long int sz;
printf("Enter the size of array::");
scanf("%lld",&sz);
array_generate(sz);
}
long long int array_generate(long long int sz){
long long int randArray[sz];
long long int i;
for(i=0;i<sz;i++)
randArray[i]=rand()%1000; //Generate number between 0 to 1000
}
Your code is creating very large arrays as local variables. Locals typically reside on the stack which is limited in size, so by defining such a large local array you are overflowing the stack, causing your program to crash.
Use malloc instead to dynamically allocate memory on the heap which is much larger.
long long int *randArray = malloc(sz * sizeof *randArray);
As #dbush pointed out, you can't dynamically allocate such large arrays on the stack. You must use the heap instead.
As a general advise I would say never write something like that unless you really know what you're doing :
int array[dynamic_size];
Instead use a fixed size array like so :
#define FIXED_SIZE 200
[...]
int array[FIXED_SIZE];
// or int array[200];
Or use malloc (3).
Regarding your code, what is usually done in C is that the caller allocates memory and passes its pointer to the function initializing it. So your main would look like that :
int main(){
srand(time(NULL));
long long int sz;
printf("Enter the size of array::");
scanf("%lld",&sz);
// "sizeof *array" is the same as "sizeof(long long int)" but better because if you change the type of your array later, you won't have to change it twice (better from a maintainability POV)
long long int *array = malloc(sz * sizeof *array);
array_generate(array, sz);
array_process(array, sz);
free(array);
array = NULL; // not mandatory
}
Can anyone please tell me why i have a segmentation fault here?
float element(float** mat,int k, int l, int block_size){
int i_start=k*block_size;
int i_end=(k+1)*block_size-1;
int j_start=l*block_size;
int j_end=(l+1)*block_size-1;
float somma=0;
int c=0;
float media=0;
for(;i_start<=i_end;i_start++){
for(;j_start<=j_end;j_start++){
somma+=mat[i_start][j_start];
c++;
}
}
media=somma/c;
return media;}
Mat* matrixScale(Mat* m, int block_size) {
Mat* new=(Mat*) malloc(sizeof(Mat));
new->rows=m->rows/block_size;
new->cols=m->cols/block_size;
new->row_ptrs=(float**) malloc(new->rows*sizeof(float*));
int i,j,z;
for(z=0;z<new->rows;z++)
new->row_ptrs[z]=(float*) calloc(new->cols,sizeof(float));
for(i=0;i<m->rows;i++){
for(j=0;j<m->cols;j++){
new->row_ptrs[i][j]=elements(m->row_ptrs,i,j,block_size);
}
}
return new;}
I tried using a debugger but it just says that the problem is inside the element function.
Your post needs more detail. The line of the crash, the definition of Mat, what the intent is. etc.
For the future see how to make a Minimal example. You will get a quicker response with the 'C' tag as well. Be sure to post a detailed question or you will get down voted and castigated.
There are multiple issues with the code. The problem seems to around the block size variable.
int i_start=k*block_size;
int i_end=(k+1)*block_size-1;
int j_start=l*block_size;
int j_end=(l+1)*block_size-1;
Passing in a particular i,j combination and multiplying by block size will go past the end of the row_ptrs array. Reading/writing past the end of the array is undefined and will result in a crash generally. Perhaps you meant divide?
This bit is also odd.
for(i=0;i<m->rows;i++){
for(j=0;j<m->cols;j++){
new->row_ptrs[i][j]=elements(m->row_ptrs,i,j,block_size);
}
}
The max index of rows is [m->rows/block_size][m->cols/block_size] but you are going all the way to [m-rows][m->cols]. Unless blocksize is 1 this will crash as it writes past the end of the array.
I need to fill 2-d array with 0s. But compiled program falls with this error. What's wrong?
int main()
{
int vert[1001][1001];
int hor[1001][1001];
int dudiag[1416][1416];
int uddiag[1416][1416];
int n, k, m;
int row, col;
int i, j;
int answer = 0;
for(i = 0; i <= 1000; i++){
for(j = 0; j <= 1000; j++){
vert[i][j] = 0;
hor[i][j] = 0;
}
}
...
}
When cycle is commented out, it works properly.
The problem is that you are trying to allocate too much memory in the automatic store (AKA "on the stack"). When you comment out the cycle, the compiler optimizes out the allocation along with the now-unused variables, so you do not get a crash.
You need to change the allocation to either static or dynamic memory (AKA "the heap") to fix this problem. Since the issue is inside main, making the arrays static would be an appropriate choice.
int main()
{
static int vert[1001][1001];
static int hor[1001][1001];
static int dudiag[1416][1416];
static int uddiag[1416][1416];
...
}
In functions other than main you could make these arrays dynamic, allocate them using malloc/calloc, and then free them once your program has finished using them.
What's wrong?
You are trying to reserve on stack several 4MB arrays. On many Linux distributions, the default stack size is 8MB (you can change this with ulimit -s unlimited).
Even with unlimited stack, the Linux kernel will not extend stack by more than some constant, so ulimit -s unlimited may not help avoiding the crash.
As dasblinkenlight's answer says, if you need arrays that large, allocate them dynamically.
Finally, an explicit for loop is an inefficient way to zero out an array. Using memset is likely to be much more efficient, and requires much less code.
I have written the following program:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
void inttobusn(int val, int n, char* bus)
{
int i;
unsigned int digit;
for (i=0; i < n; i++) {
digit = pow(2, (n-1-i));
if (digit <= val) {
val -= digit;
bus[i] = '1';
//printf("hello %c",bus[i]);
} else {
bus[i] = '0';
}
}
}
main(){
char* bus;
inttobusn(37,8,bus);
int i=0;
//printf("%s",bus);
for(i=0;i<12;i++){
printf("%c",bus[i]);
}
}
But on running it doesn't print the elements of the array bus. It doesn't print anything. I am unable to figure out what is wrong. Please could someone point out?
Your code is buggy! you don't allocate memory for the bus[] array, and are trying to access values at garbage location as e.g bus[i] = 0; -- Undefined Behavior in C standard, Undefined means you can't predict how your code will behave at runtime.
This code compiled because syntax-wise the code is correct but at runtime the OS will detect illegal memory access and can terminate your code. (interesting to note: as OS detects memory right violation by a process -- An invalid access to valid memory gives: SIGSEGV And access to an invalid address gives: SIGBUS). In the worst case your program may seem execute without any failure, producing garbage results.
To simply correct it define bus array as char bus[N]; else allocated memory dynamically using void* malloc (size_t size);
Additionally, suggestion to your from #Lochemage and #Ran Eldan:
You need to declare bus with a specific size, like char bus[12]. It has to be at least large enough to fit 12 chars because your for loop at the end is iterating through that many (and you can check your code working with this suggestion #codepade).
Also there is no return type to main() in your code, its should be int main(void).
There is no memory allocated to bus so this is an undefined behavior. Either write
char bus[some sufficient size];
or use malloc, realloc to reserve memory.
You didn't initialize you bus variable.
char* bus = malloc(8 * sizeof(char));
I've written the following code for a codechef problem. Everytime I submit I get a NZEC error. Any ideas?
#include<stdio.h>
int main()
{
int n=0,s=0;
int a[2001][2001]={0},i=0,k=0,c=0;
scanf("%d%d",&n,&s);
for(i=0;i<s;i++)
{
scanf("%d",&c);
for(k=0;k<c;k++)
{
scanf("%d",&a[i][k]);
}
}
printf("%d\n",s);
for(i=0;i<s;i++)
printf("%d\n",i);
return 0;
}
Your array is created in the stack, which might be too small for it.
Essentially in multi-threaded applications, each thread will have its own stack. But, all the different threads will share the heap.
So in your int main() function when you define the array you are actually creating it in the stack (it's the "main thread"). If you move it outside of the function and define it globally, it will be created in the heap.(This is a bit more complicated than what I've just described, e.g. if you create an object using the new keyword inside a function it will be created in the heap etc. but I won't be explaining that now)
You can check the stack size by using ulimit -s.
Also note that the stack is generally faster than the heap because of the way memory is allocated.
int a[2001][2001] is too large for stack, declare it as a global variable.
int a[2001][2001]={0};
int main()
{
int n=0,s=0;
int i=0,k=0,c=0;
scanf("%d%d",&n,&s);
/* etc. */
}