#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.
Related
hi im trying to make my array increase its size with realloc from function when even number is typed, but the compiler is displying Segmentation Fault whatever number I type.Any ideas how can i fix this?
#include <stdio.h>
#include <stdlib.h>
int MakeArray(int n,int *ptr)
{
ptr = (int*) malloc(n*sizeof(int));
if(ptr==NULL)
{
puts("Allocation failed");
}
return *ptr;
}
int ReAllocArray(int n,int *ptr)
{
ptr = (int*) realloc(ptr,n*sizeof(int));
if(ptr==NULL)
{
puts("Reallocation failed");
}
return *ptr;
}
int main() {
int n;
int *ptr=NULL;
puts("Enter size of n");
scanf("%d",&n);
MakeArray(n,ptr);
puts("Entering even number is increasing the size of the array by 1");
for(int i =0;i<n;++i)
{
scanf("%d",&ptr[i]);
if(ptr[i]%2==0)
{
++n;
ReAllocArray(n,ptr);
}
}
puts("Your array is:");
for(int i =0;i<n;i++)
{
printf("%d",ptr[i]);
}
return 0;
}
You need to pass pointer to pointer to int to modify it or/and return the reference to the allocated memory
int *MakeArray(size_t n, int **ptr)
{
if(ptr)
{
*ptr = malloc(n*sizeof(**ptr));
if(!*ptr)
{
puts("Allocation failed");
}
}
return *ptr;
}
Same when you realloc
int *ReAllocArray(size_t n, int **ptr)
{
int *tmp = NULL;
if(ptr)
{
tmp = realloc(*ptr,n * sizeof(**ptr));
if(!tmp)
{
puts("Reallocation failed");
}
else
{
*ptr = tmp;
}
}
return tmp;
}
When you call it you need to pass pointer to pointer:
MakeArray(n,&ptr);
ReAllocArray(n,&ptr);
It would be worth checking what those functions return to know if allocations succeeded.
Also:
Use the correct type for sizes (size_t nor int)
Do not cast the result of malloc/realloc. If it does not compiler you are using the wrong (C++) compiler to compile the C code.
Use objects not types in sizeofs
When realloc use a temporary variable. Otherwise, you may have a memory leak
BTW you do not need the MakeArray function at all as realloc will work fine when you pass NULL pointer (it will simple not copy any data to the allocated memory)
This code keeps saying segmentation fault.
for(i=0; i<(numTopps-1); i++)
{
if(kcalTopp[i]<kcalTopp[i+1])
{
temp=*kcalTopp[i];
*kcalTopp[i]=*kcalTopp[i+1];
*kcalTopp[i+1]=temp;
}
}
I think above part is a problem.
but I can't figure what is the problem
#include <stdio.h>
#include <stdlib.h>
void sort(int *kcalTopp[], int numTopps);
int main(void)
{
int numTopps, doughPrice, eachToppPrice, kcalDough, i, j, totalKcal, highest, kcalperDol;
scanf("%d %d %d %d", &numTopps, &doughPrice, &eachToppPrice, &kcalDough);
int *kcalTopp;
kcalTopp=(int*)malloc(sizeof(int)*numTopps);
for(i=0; i<numTopps; i++)
{
scanf("%d", &kcalTopp[i]);
}
totalKcal=kcalDough;
highest=totalKcal/doughPrice;
sort(&kcalTopp, numTopps);
for(i=0; i<numTopps; i++)
{
for(j=0; j<=i; j++)
{
totalKcal=totalKcal+kcalTopp[j];
kcalperDol=totalKcal/(doughPrice+i*eachToppPrice);
if(kcalperDol>highest)
{
highest=kcalperDol;
}
}
}
printf("%d", highest);
return 0;
}
void sort(int *kcalTopp[], int numTopps)
{
int temp, i;
for(i=0; i<(numTopps-1); i++)
{
if(kcalTopp[i]<kcalTopp[i+1])
{
temp=*kcalTopp[i];
*kcalTopp[i]=*kcalTopp[i+1];
*kcalTopp[i+1]=temp;
}
}
}
Indeed, your problem is the sort function you described, as you suspected. Are you aware what *kcalTopp[i]=*kcalTopp[i+1]; does exactly? You get as parameter an int *array[] which is equivalent to int **array (you can see it as an array of arrays of ints). So when you tell C to access array[i] you will access the i-th array. This is a pointer, and in fact *kcalTopp[i] will be the first element from the i-th array. What you are doing here is swapping first elements from the arrays, but in practice you have a single array of ints (or more technically, an array of length 1 of arrays). The simplest fix is to write:
temp=(*kcalTopp)[i];
(*kcalTopp)[i]=(*kcalTopp)[i+1];
(*kcalTopp)[i+1]=temp;
just to change the precedence of the operators. Now, what we achieved is: we take the first array from the array list (it's the only one we have, isn't it?) with (*kcalTopp); this is an int *, not int ** anymore. Now you can safely access the i-th element from it.
Without parentheses, you would first access the i-th array, because in *kcalTopp[i], the [i] part will execute before the * part.
Anyway, to simplify things, you are not required to take as parameter an int *kcalTopp[], you can simply take int kcalTop[] or int *kcalTopp and not use * anymore:
temp = kcalTopp[i];
kcalTopp[i] = kcalTopp[i+1];
kcalTopp[i+1] = temp;
The original code in your post is using an extra (unnecessary) layer of indirection for kcalTopp, resulting in attempts to manipulate an array of addresses (pointers) as opposed to manipulating int values pointed to in memory. This in turn is likely to be the reason you are seeing segmentation faults, which occur when attempting to access memory that you do not own. For some input values, and depending on what day you run your program, it may run, and it may crash.
(This is sometimes referred to as undefined behavior, and is the reason that the problem will not always manifest itself, making you think your program is flawless, when it is not.)
The following contains edits to your original code for the purpose of illustrating some of the suggestions in comments. (not to fix every logic error.) The edits do include treating kcalTopp as a pointer to int memory as opposed to an array of int *. See in-line comments for clarifications:
//void sort(int *kcalTopp[], int numTopps);//*kcalTopp[] is an array of pointers
void sort(int *kcalTopp, int numTopps);//*kcalTopp is a pointer to 'int' memory
int main(int argc, char *argv[])
{
int numTopps, doughPrice, eachToppPrice, kcalDough, i, j, totalKcal, highest, kcalperDol;
//scanf("%d %d %d %d", &numTopps, &doughPrice, &eachToppPrice, &kcalDough);
if(argv != 5) //simple reading in of command line args
{
printf("4 input values required. Exiting");
return 0;
}
//note, each of these calls includes simple for test for success before going on
numTopps = strtol(argv[1], (char **) NULL, 10);
if(errno == ERANGE) {printf("argv[1] Bad input, exiting"); return 0;}
doughPrice = strtol(argv[2], (char **) NULL, 10);
if(errno == ERANGE) {printf("argv[2] Bad input, exiting"); return 0;}
eachToppPrice = strtol(argv[3], (char **) NULL, 10);
if(errno == ERANGE) {printf("argv[3] Bad input, exiting"); return 0;}
kcalDough = strtol(argv[4], (char **) NULL, 10);
if(errno == ERANGE) {printf("argv[4] Bad input, exiting"); return 0;}
int *kcalTopp;
//This statement (without cast) is sufficient to create memory for kcalTopp
kcalTopp = malloc(sizeof(int)*numTopps);
if(!kcalTopp)//should always test before using memory
{
printf("memory allocation failed, exiting");
return 0;
}
for(i=0; i<numTopps; i++)
{
scanf("%d", &kcalTopp[i]);
}
totalKcal=kcalDough;
highest=totalKcal/doughPrice;
//sort(&kcalTopp, numTopps);
// ^ not needed
sort(kcalTopp, numTopps);
for(i=0; i<numTopps; i++)
{
for(j=0; j<=i; j++)
{
totalKcal=totalKcal+kcalTopp[j];
kcalperDol=totalKcal/(doughPrice+i*eachToppPrice);
if(kcalperDol>highest)
{
highest=kcalperDol;
}
}
}
printf("%d", highest);
return 0;
}
void sort(int *kcalTopp, int numTopps)//note removal of []
{
int temp, i;
for(i=0; i<(numTopps-1); i++)
{
if(kcalTopp[i]<kcalTopp[i+1])
{
temp=kcalTopp[i];//note removal of '*' from all kcalTopp
kcalTopp[i]=kcalTopp[i+1];
kcalTopp[i+1]=temp;
}
}
}
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));
I have this problem I need to solve. I am given a program which is supposed to allocate memory to create an array of doubles, but something is wrong with it. Basically, main and the function create_array are broken, and I need to fix it. The solution I came up with comes up with a segmentation error and i am not sure why.
First off I decided to delete the "free(array)" in main b/c array is a pointer which does not exist in heap from my understanding.
I tried changing the function "create_array" to the following
void create_array(double *x, unsigned long n) {
double *d = malloc((int)n *sizeof(double));
if(d == NULL){
printf("Sorry Memory Not Available. Program Terminated.\n");
exit(1);
}
x=d;
free(d);
}
Here is what I was provided with:
int main(void) {
printf("\nProgram started...\n");
double *array = NULL;
int n = 20;
create_array(array, n);
if( array != NULL) {
populate_array(array, n);
// displays half of the values of the array
for(int i = 0; i < n/2; i++){
printf("%f\n", *array++);
}
// According to C standard, the program's behaviour, after the following
// call to the function free is considered "Undefined" and needs to be
// fixed.
free(array);
}
printf("Program terminated...\n");
return 0;
}
// THE FOLLOWING FUNCTION IS NOT PROPERLY DESINGED AND NEEDS TO BE FIXED
void create_array(double *x, unsigned long n) {
x = malloc(n *sizeof(double));
if(x == NULL){
printf("Sorry Memory Not Available. Program Terminated.\n");
exit(1);
}
}
void populate_array(double *array, int n) {
int i;
for(i = 0; i < n; i++)
array[i] = (i + 1) * 100;
}
When I run the code with my edit, i get segmentation error. When I run the code with no changes, it simply outputs "program started \n program terminated".
The problem is, in both code and snippet provided, the variable assigned by malloc's return value lives until the function returns. So you need to use pointer-to-pointer. Moreover, in the first snippet, if you free the area allotted already, you can't use the space anymore.
void create_array(double **x, unsigned long n) {
*x = malloc(n *sizeof(double));
if(*x == NULL){
printf("Sorry Memory Not Available. Program Terminated.\n");
exit(1);
}
}
In main, you can call it as create_array(&array, n);.
There are several errors in create_array. x is a local variable, so it will not change. Also, you free the memory after initialization, which in practice makes the whole function useless. Free should be done after you're done with the memory.
Here is a corrected version
void create_array(double **x, unsigned long n) {
double *d = malloc((int)n *sizeof(double));
if(d == NULL){
printf("Sorry Memory Not Available. Program Terminated.\n");
exit(1);
}
*x=d;
}
And then you call it like this:
double *p;
create_array(&p, size);
/* Do something */
free(p);
But, IMHO it would be better to do like this:
double *create_array(size_t n) {
double *d = malloc(n*sizeof(*d));
if(d == NULL){
fprintf(stderr, "Sorry Memory Not Available. Program Terminated.\n");
exit(1);
}
return d;
}
Changes:
Returns the pointer instead of using an output parameter
Use size_t instead of unsigned long
Print errors to stderr insteadd of stdio
Use malloc(size *sizeof(<var>)) instead of malloc(size * sizeof(<type>))
And here is the call:
double *p = create_array(&p, size);
/* Do something */
free(p);
I have a function that finds Roman numerals of numbers passed in an array and stores them in a string array and returns the string array to the main(). But when I try to access the returned string array in main(), the code fails due to segmentation fault. Can someone please explain me why this is happening and how can i correct my code?
Added comments in the code where segmentation fault is seen and where it works fine. Thanks alot for your time and help.
int find_lookup_index(int temp)
{
int j=0;
while(1)
{
if(temp>=lookup_int[j] && temp<lookup_int[j+1])
break;
j++;
}
return j;
}
char** romanizer(int num_size, int* num)
{
int i,j,temp;
char result[num_size][20];
for(i=0;i<num_size;i++)
{
strcpy(result[i],"\0");
if(num[i]%1000 == 0)
{
strcpy(result[i],"M");
continue;
}
j=find_lookup_index(num[i]);
temp=num[i];
while(temp>0)
{
strcpy(result[i],strcat(result[i],lookup_char[j]) );
temp = temp - lookup_int[j];
j = find_lookup_index(temp);
}
}
**/* WORKS CORRECTLY HERE */**
for(i=0;i<num_size;i++)
printf("%s\n",result[i]);
return (char **)result;
}
int main()
{
int size,i;
char **result;
int arr[3] = {3,11,499};
result = romanizer(3,arr);
**/* NOT WORKING - SEGMENTATION FAULT - WHY ? */**
for(i=0;i<3;i++)
printf("%s\n",result[i]);
return 0;
}
result is defined on the stack, and is "free"'d off the stack when romanizer is finished executing. So when your main tries to use it, it gets a segmentation fault.
The solution is to malloc the data structure (which allocates it on the heap rather than the stack), and have the caller free it when it's no longer needed.
Inside your romanizer function, you are allocating result on the stack, which is freed automatically for you upon return from your function. When you try to use it in main it is already gone.
You must either allocate it on the heap with a new/Malloc and then delete/free it in main, or allocate it in main and pass it in as a parameter instead of a return value.