Segmentation fault in a two dimensional array using scanf - c

I've been getting segmentation fault in this piece of code, in the part where I scanf for the values of the board. In the beginning, I scan two times for the dimensions.
#include <stdio.h>
#include <stdlib.h>
#include "maxsum.h"
int main() {
int x,y,n,m,**board;
scanf("%d %d",&n,&m);
board=malloc(n*sizeof(int));
if (board==NULL) {
printf("Unable to allocate memory \n");
return 1;
}
for (x=0;x<n;x++) {
*(board+x)=malloc(m*sizeof(int));
if (*(board+x)==NULL) {
printf("Unable to allocate memory \n");
return 1;
}
}
for (x=0;x<n;x++) {
for (y=0;y<m;y++) {
scanf("%d",&board[x][y]); // the error happens in this line ,and only when variable x is about to become n-1 when n>4 (very confused as to why)//
}
}
printf("%d \n",Solve(n,m,board)); //not relevant //
return 0;
}

You're not allocating the right amount of memory:
board=malloc(n*sizeof(int));
You're setting up board as an array of int *, but you're only allocating space for an array of int. Most likely an int is smaller than an int * on your system, so you're not allocating enough. You subsequently write past the end of allocated memory resulting in undefined behavior.
Change this allocation to:
board=malloc(n*sizeof(int *));
Or better yet:
board=malloc(n*sizeof(*board));

Related

Program overflows on large struct array value

The code is an implementation of the Gift Wrapping Algorithm. The input file is of the form 'X Y Z' on each line, and I don't need to consider the Z co-ordinate. The code works fine for smaller N like 100000 but gives segmentation fault for larger N value. Can some one explain me the reason for it?
#include <stdio.h>
#include <stdlib.h>
#define N 200000
struct Point{
double x,y;
};struct Point p[N];
int ori(struct Point p1, struct Point p2, struct Point p3);
int main(){
FILE *fp,*fp2;
fp2=fopen("out.txt","w");
int i=0;
fp=fopen("sample.txt","r");
if(fp==NULL){
printf("File not found!\n");
exit(0);
}
double g;
for(i=0;i<N;i++)
fscanf(fp,"%lf %lf %lf",&p[i].x,&p[i].y,&g);
int l=0;
for(i=1;i<N;i++){
if(p[i].x<p[l].x){
l=i;
}
}
int base=l,q;
int chullin[N];
for(i=0;i<N;i++)
chullin[i]=-1;
while(true){
q=(base+1)%N;
for(i=0;i<N;i++)
if(ori(p[base],p[i],p[q])==1)
q=i;
chullin[base]=q;
base=q;
if(base==l)
break;
}
int cnt=0;
int a[26];
for(i=0;i<N;i++)
if(chullin[i]!=-1){
a[i]=i;
fprintf(fp2,"%f %f %d\n",p[i].x,p[i].y,i);
cnt++;
}
return 0;
}
int ori(struct Point p1, struct Point p2, struct Point p3){
int val=p1.x*(p2.y-p3.y)-p1.y*(p2.x-p3.x)+(p2.x*p3.y-p3.x*p2.y);
if(val==0)
return 0;
if(val>0)
return 1;
else return -1;
}
you are totally overflowing the int array 'a' or at least accessing non-existent values within the array, which is on the stack... if chullin[i] != -1 for more than 26 points... or if chullin[i] where i>25, you are writing randoms on the stack.
int a[26];
for(i=0;i<N;i++)
if(chullin[i]!=-1){
a[i]=i; //problem here.
fprintf(fp2,"%f %f %d\n",p[i].x,p[i].y,i);
cnt++;
}
The problem is not in the array p, but in the array chullin. Try to dynamically allocate the array, using the malloc function:
int *chullin = (int*)malloc(sizeof(int)*N);
// do whatever you want with chullin
free(chullin);
Edit: I will try to explain the cause of the Segmentation fault. When you create a non-dynamic array inside a function, it is allocated in the heap. The heap has limited size, so when you declare a large array, the heap overflows. When you use malloc, you dynamically allocate the array, which means that it is allocated in the stack. The stack has much bigger size than the heap, so you are able to create larger arrays. Global arrays are also allocated in the stack, that's why you needn't allocate them dynamically...
Edit[2]: Array a has size 26, which means that when N is larger than or equal to 26 you will be accessing invalid memory locations, causing segmentation fault.

Segmentation fault initialising an array

The following program produces a segmentation fault, and I'm not sure why. malloc succeeds, so it doesn't seem to be an initialisation error, but for some reason, it segfaults when I access the 253900th element. The array is only 4 * 1e6 bytes, or a about a Megabyte.
This does produce a lot of output
#include <stdlib.h>
#include <stdio.h>
int *long_array(size_t N) {
int *arr = (int *) malloc(N);
if (arr == NULL) { printf("could not malloc"); exit(1); }
for (size_t i = 0; i < N; i++) {
printf(".. %ld ", i);
arr[i] = 10;
}
printf("done with loop\n");
return arr;
}
int main(void) {
int *arr = long_array(1000000);
printf("%d", arr[5050]);
return 0;
}
I compile this with gcc -std=c99 and run the output to see the final few numbers printed before the segfault:
253899 .. 253900 .. 2
segmentation fault (core dumped) ./a.out
I don't understand why accessing a particular index is causing the segmentation fault. I can guess that I must be accessing a memory location outside of my processes address space, but this seems like a bug if I successfully allocated the memory from within my address space.
malloc(sizeof(int)*N) instead of malloc(N).
Otherwise you'd get an array of N bytes, not N integers.
use
int *arr = (int *) malloc(N * sizeof(int));
Your code is correct but the problem here is that your did not consider the size of an integer
while allocating memory. You just allocated :
int *arr=(int *)malloc(N);
here you just allocated size of N but you have to consider size of integer in your machine.
If you allocate just 10000000 size of memory and sizeof(int) in you machine is 4 then it can just access (10000000/4) memory .........
So you have to allocate memory like:
int *arr=(int *)malloc(N*sizeof(int))
or
int *arr=(int *)malloc(N*sizeof(*arr));

Reading values from the memory block which created/mofied malloc realloc?

As I ask how can I read values from the memory which was put into a memory block by malloc/realloc?
I have a program which creates 2 memory blocks at first and extends until reach 32.Its working fine but in order not to lose values after realloc I start my scanf session with an integer called koru.Koru starts with 0 at the beginning and in every realloc I make its number half of the total amount of memory so I expect not to lose the values entered before realloc sessions but now I need to read what I wrote the memory so I will be sure that I didnt overwrite how can I do that ?
#include "stdio.h"
#include "stdlib.h"
int main()
{
int size=2;
int* p1;
int* p2;
int n;
p1=(int *)malloc((size*sizeof(int)));
int b=0;
int i=0;
int koru=0;
while(size<32)
{
if(i<size){
for(i=koru;i<size;i++)
{
printf("\nEnter value:");
scanf("%d",p1);
}
}
else if(boyut=i)
{
size=size*2;
p2 = (int*) realloc (p1,size*sizeof(int));
p1=p2;
koru=size/2;
printf("\nNOt enough size we make it %d also we protect %d that amount of memory"size,koru);
}
}
return 0;
}
I thought putting a array[i]=p1; and reading it after while loop will solve the problem but later I figured out that its cheating I am not reading from the memory block just reading from another array so this wont work too can somebody lead the way for me please ?
What my program does:
2 blocks memory malloc
takes values and fills it
When it fills improves the memory size multiplying by 2 realloc
starts reading from half number so it dont rewite
continues this progress until it reaches 32
Edit:Simplified question:
I put lots of values in the memory after while loop how can I read them ?
I tried to read it like this but all I get is 0
int counter =0;
while (counter<koru)
{
printf("\n%d",p1[counter]);
counter++;
}
return 0;
}
The correct code which creates a memory block with malloc and extends it with realloc after 32 it exits while loop and writes everything from the p1 pointer(from memory) thanks for help.
Working Code below:
#include "stdio.h"
#include "stdlib.h"
int main()
{
int boyut=2;
int* p1;
int* p2;
int n;
p1=(int *)malloc((boyut*sizeof(int)));
int b=0;
int i=0;
int koru=0;
while(boyut<16)
{
if(i<boyut){
for(i=koru;i<boyut;i++){
printf("\nDeğer Girin:");
scanf("%d", &p1[i]);
}
}
else if(boyut=i)
{
boyut=boyut*2;
p2 = (int*) realloc (p1,boyut*sizeof(int));
p1=p2;
koru=boyut/2;
printf("\nBoyut yetersiz yeni boyutu %d yapıyoruz önceki %d kadar alanı korumaya aldık",boyut,koru);
}
}
int counter =0;
while (counter<koru)
{
printf("\n%d",p1[counter]);
counter++;
}
return 0;
}
I'm not sure exactly what you are asking here, but to access the values in the memory, just use p1 as an array. p1[3] would give you the 4th integer in the memory block.
Just be sure to respect the array bounds.
Bonus problem: you're not even filling the array, you're overwriting the first element each time you input.
The simple solution is to remove p2 entirely and treat p1 as an array:
...
scanf("%d", &p1[i]);
...
Then to read:
int n;
for (n=0; n<i; n++)
printf("%d ", p1[n]);
However, if you want to do it with two pointers instead of array indexing, you need one pointer to track the whole array for malloc and realloc, and the other to track where the current value is for reading/writing.
Initially the array is empty, so they are the same:
p1 = (int *)malloc(boyut * sizeof(int));
p2 = p1;
...
Input only uses the read/write pointer, and increments it each time:
...
scanf("%d", p2++);
...
Memory management only uses the "base" pointer
...
p1 = (int *)realloc(p1, boyut * sizeof(int));
...
(note you should strictly use a temporary variable for the return value of realloc() to check for failure, otherwise you could lose the value of p1)
Then to read we reset the read/write pointer to the start, and iterate through:
int n;
p2 = p1;
for (n=0; n<i; n++)
printf("%d ", *p2++);

Segmentation Fault in C using calloc

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int queensonboard(int n,int m)
{
int count=0,i,j,flag,x[100];
char **board;
/* board= (char**)calloc(sizeof(char*),n);
for(i=0;i<n;i++)
{
board[i]= (char*)calloc(sizeof(char),m);
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%c",&board[i][j]);
}
}*/
// x==(int*)calloc(sizeof(int),n);
flag=0;
for(i=0;i<n;i++)
{
x[i]=0;
}
while(i>0)
{
while(x[i]<m)
{
x[i]++;
// if(board[i][x[i]]!='#')
// {
for(j=0;j<i;j++)
{
if(x[j]==x[i])
{
flag=1;
}
else if(x[j]-x[i]==abs(j-i))
{
flag=1;
}
else
{
flag=0;
}
}
if(flag==0 && i==n-1)
{
count++;
}
else if(flag==0)
{
i++;
}
//}
}
x[i]=-1;
i--;
}
printf("%d\n",count);
}
int main() {
int i,n,m,j;
scanf("%d",&i);
for(j=1;j<=i;j++)
{
scanf("%d %d",&n,&m);
queensonboard(n,m);
}
return 0;
}
This is the code. The program gives segmentation fault on dynamically allocating any of the arrays x or board.(Commented here.)
That is when i try to allocate with calloc.
Couldnt really figure out why this is happening. Tried changing thins and that but still happening.
The definition of calloc is as follows:
void *calloc(size_t num, size_t size);
num Number of elements to allocate.
size Size of each element.
You have your arguments swapped. It should be like this:
board = calloc(n, sizeof(char *));
for(i = 0; i < n; i++)
{
board[i]= calloc(m, sizeof(char));
}
Also, this line is incorrect:
x == (int*)calloc(sizeof(int), n);
This, is comparing the address of x to the address that calloc returns. The logic is incorrect too. The way you have x defined, it is an array of 100 ints.
If you want an array of int pointers, you need to do this:
int *x[100];
If you want a pointer to array of 100 ints, you need to do this:
int (*x)[100];
If you're simply trying to allocate memory for x, you've already accomplished that with your declaration:
int x[100];
The obvious explanation for a segmentation fault is that you are de-referencing an invalid pointer. The obvious way for that to happen would be for any of the calls to calloc to return NULL. And calloc does that when it fails. You are not checking the return value of calloc for errors and I think it very likely that one of the calls returns NULL because you supplied invalid parameters.
So, debug the problem by checking the return value of the calls to calloc, and checking the input parameters that you pass. I know it's frustrating to have to do this, but you must check for errors in all user input, and you must check the return values of all calls to memory allocation functions.
This line
x==(int*)calloc(sizeof(int),n)
where you perform comparison rather than assignment is also clearly problematic. You meant:
int *x = calloc(n, sizeof(int));
And yes, you have the arguments to calloc swapped as others point out. You should certainly fix that but I do not believe that to be the cause of your problem.

Trouble deallocating memory using free()

I have trouble deallocating memory that I allocated using malloc. The program runs fine until it the part where it's supposed to deallocate memory using free. Here the program freezes. So I was wondering what the problem could be since I'm just learning C. Syntactically the code seems correct so could it be that I need to delete all the stuff in that location before deallocating memory from that location or something else?
Here's the code.
// Program to accept and print out five strings
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NOOFSTRINGS 5
#define BUFFSIZE 255
int main()
{
char buffer[BUFFSIZE];//buffer to temporarily store strings input by user
char *arrayOfStrngs[NOOFSTRINGS];
int i;
for(i=0; i<NOOFSTRINGS; i++)
{
printf("Enter string %d:\n",(i+1));
arrayOfStrngs[i]=(char*)malloc(strlen(gets(buffer)+1));//calculates string length and allocates appropriate memory
if( arrayOfStrngs[i] != NULL)//checking if memory allocation was successful
{
strcpy(arrayOfStrngs[i], buffer);//copies input string srom buffer to a storage loacation
}
else//prints error message and exits
{
printf("Debug: Dynamic memory allocation failed");
exit (EXIT_FAILURE);
}
}
printf("\nHere are the strings you typed in:\n");
//outputting all the strings input by the user
for(i=0; i<NOOFSTRINGS; i++)
{
puts(arrayOfStrngs[i]);
printf("\n");
}
//Freeing up allocated memory
for(i=0; i<NOOFSTRINGS; i++)
{
free(arrayOfStrngs[i]);
if(arrayOfStrngs[i] != NULL)
{
printf("Debug: Memory deallocation failed");
exit(EXIT_FAILURE);
}
}
return 0;
}
You misuse strlen() and this results in buffer overrun:
arrayOfStrngs[i]=(char*)malloc(strlen(gets(buffer)+1)); //pointer from gets() is incremented and passed to strlen() - that's wrong
should be
arrayOfStrngs[i]=(char*)malloc(strlen(gets(buffer))+1); //pointer from gets() is passed to strlen(), then returned value is incremented - correct
also free() doesn't change the pointer passed to it. So that
char* originalValue = pointerToFree;
free( pointerToFree );
assert( pointerToFree == originalValue ); //condition will always hold true
and so in your code freeing memory should just be
//Freeing up allocated memory
for(i=0; i<NOOFSTRINGS; i++)
{
free(arrayOfStrngs[i]);
}
arrayOfStrngs[i]=(char*)malloc(strlen(gets(buffer)+1));//calculates string length and allocates appropriate memory
Shouldn't that be
arrayOfStrngs[i]=(char*)malloc(strlen(gets(buffer))+1);

Resources