Solve segmentation fault error in C - c

I am trying to store the sum 1/k^2 in an array using this code:
int main()
{
int i,n, e;
double terms[n];
double x, y;
printf(" Introduce n\n");
scanf("%d", &n);
y=1;
i=0;
while(e<n)
{
x=1/((y)*(y));
printf("x is %.16lf\n",x);
terms[i]=x;
printf("terms is %.16lf\n", terms[i]);
y++;
i++;
e++;
}
}
And I get the "segmentation fault" error. Why is this happening? How can I avoid it?
I am programming in C

n is garbage in double terms[n]; that causes undefined behaviour. Enable compiler warning by compiling with gcc -Wall and observe. Never ignore warnings.
Initialize n before declaring terms[n] OR
printf(" Introduce n\n");
scanf("%d", &n);
double terms[n];
Also e is uninitialized, initialize it.
e = 0 ;
while (e < n){
/* code */
}

When declaring an array with n elements (double terms[n];), the allocation of said array is done in the compilation stage. Because you left your n variable un-initialized, it has indeterminate value (random from the user perspective), so you don't know what is the size of said array.
Scanning an int into n later, does not help at all as it is done in the run-time (and also, it is done AFTER the array declaration. It could have worked if you have used malloc for the allocation AFTER the scanf).
Anyway, you currently have an array with "random" size, and accessing it is Undefined Behavior -> segfault

The crash comes from undefined size of the terms[n] array. You are crossing array memory boundaries.
A few variables are not initialized:
double terms[n]; // n is not initialized
while (e<n){ // e is not initialized
You have many choices to properly build terms array (marked in the code as well):
1) Decide upfront on the specific size of the array. (This is not flexible approach!)
2) Allocate array dynamically when you read n.
3) Declare terms[n] after reading n.
Test program:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i;
int n;
int e = 0;
// 1. One of the 3 choices - thus is a rigid one
// double terms[TERMS_SIZE]; // make TERMS_SIZE big enough, read n has to be less than TERMS_SIZE
double x, y;
printf(" Introduce n\n");
scanf("%d", &n);
// 2.
// double *terms = malloc ( n* sizeof sizeof(double));
// or
// 3.
double terms[n];
y=1;
i=0;
while (e<n){
x=1/((y)*(y));
printf("x is %.16lf\n",x);
terms[i]=x;
printf("terms is %.16lf\n",terms[i]);
y++;
i++;
e++;
}
// If 2. used free the memory
// free(terms);
return 0;
}
Output:
4
Introduce n
x is 1.0000000000000000
terms is 1.0000000000000000
x is 0.2500000000000000
terms is 0.2500000000000000
x is 0.1111111111111111
terms is 0.1111111111111111
x is 0.0625000000000000
terms is 0.0625000000000000

Related

function declaration and call and definition in c

Why is this code not running after printing of array if I take value of n>=9?
#include <stdio.h>
#include <math.h>
float mean_function(float array[],int n);
int main() {
int i,n;
float array[n],mean,sum=0,s2,summation,deno,C[i],elements;
printf("Enter No of Elements\n");
scanf("%d",&n);
printf("Enter Elements\n");
for(i=0;i<n;i++){
scanf("%f",&array[i]);
printf("%f",array[i]);
}
printf("sample variance(s2) : (sum((x-mean)*(x-mean)))/(n-1) /n");
printf("population variance(sigma2) : (sum((x-u)*(x-u))/n");
mean_function(array,n);
for(i=0;i<n;i++) {
deno=((array[i]-mean)*(array[i]-mean));
C[i]=deno;
summation=summation+C[i];
}
s2=((summation)/(n-1));
printf("s2=%f \n",s2);
}
float mean_function(float array[],int n) {
int i;
float sum=0,mean;
for(i=0;i<n;i++){ sum=sum+array[i]; }
mean=(sum/n);
return mean;
}
Why is this code not running after printing of array if I take value
of n>=9?
Some thoughts about your code (and about building programs in steps):
Arrays in C don't change in size once defined. VLAs are out for a variety of reasons. malloc() is in.
Use double, unless there is a specific reason to use floats.
Define and initialize one variable per line. Uninit vars can only result in an error as mentioned by #Jens.
Function declarations at the top (which you have done)
During development, there is no need to complicate things with a scanf (at least initially). It only adds an unwarranted layer of complexity. If you are testing statistical functions (mean, variance), put numbers in a pre-defined static array and verify functionality first.
C[i] as been declared with uninitialized i.
For this initial phase of building this program, I include a basic program.
I am not a fan of zero space between tokens (but ignore that)
Consider calling your array something other than 'array'.
Calculating the size of the samples array allows you to change the number of elements without changing anything else in code; which adds another layer of complexity to an already difficult phase.
#include <stdio.h>
#include <math.h>
double sample_mean(double* p, int n);
int main()
{
double samples[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 16.5, 2.3};
double mean = 0.0;
int size_samples = sizeof samples/sizeof(double);
printf("size_samples = %d\n", size_samples);
mean = sample_mean(samples, size_samples);
printf("Mean = %.2lf", mean);
}
// -------------------------------
double sample_mean(double* p, int n)
{
double mean = 0.0;
double total = 0.0;
for(int i = 0; i < n; i++)
total += *p++;
mean = total/n;
return mean;
}
Once this functionality is present (saved), you can start working on other stat functions. This way you can work step by step to get closer to the desired outcome.
Next up you can define sample_variance(double* p, int n) and work on that knowing that additional(new errors) are not coming from your code written so far.
Output:
size_samples = 8
Mean = 5.24
I hope it helps.
The code is likely not running because array[n] is declared with an uninitialized n. At the time you read n with scanf(), the array does not automatically "grow into the right size". You should either declare array big enough, or if you really want it to be user-defined, use malloc to allocate it (read the comp.lang.c FAQ) and all Stackoverflow questions tagged array...)
In addition, the scanf at some point fails. Note that when you enter numbers, you also have the "Enter" as a newline ('\n') in the input stream. You never read the newline so the next scanf fails.
This becomes obvious when you actually check the return value from scanf with code like this:
if (scanf("%f", &array[i]) == 1) {
/* successfully converted 1 item */
}
else {
/* scanf failed */
}
Usually what you want is to skip whitespace in the input. You do this by placing a space in the scanf format. Note that a single space tells scanf to skip any amount of white-space.
if (scanf(" %f", &array[i]) == 1) {

Unable to print the array values in C

It's just a simple C program to display the array elements taken from the user but idk why am getting the garbage values when trying to print the array... if anyone could help i would really appreciate that... thanks!!
#include <stdio.h>
#include <stdlib.h>
double *array_dou;
double* initializeDoubles(int *maxdouble)
{
printf("Enter the max. double value the program should support: ");
scanf("%d",maxdouble);
array_dou = (double *) malloc((*maxdouble)*sizeof(double));
if(array_dou == NULL)
{
printf("Error! memory not allocated.");
exit(-1);
}
return array_dou;
}
int enterDouble(double *doubles,int dcount,int maxdouble)
{
for(dcount=0; dcount<maxdouble; dcount++)
{
printf("Please enter a double value: ");
scanf("%f",&doubles[dcount]);
}
return dcount;
}
int main()
{
int maxdouble;
int dcount=0;
double *doubles;
doubles = initializeDoubles(&maxdouble);
dcount = enterDouble(doubles,dcount,maxdouble);
printf("\nDouble array\n");
for(int j=0;j<dcount;j++)
{
printf("%lf ",doubles[j]);
}
return 0;
}
Because you are calling enterDouble only once and it reads only one value. Besides you are accessing the memory out of bounds. You allocated dcount number of elements, so you can access the memory only through the indices 0 to dcount - 1, yet you are passing dcount to enterDouble, thus you are trying to write at index dcount (one past the limit).
All other entries are uninitialized, so there you have two reasons why you see "garbage": the undefined behaviour of accessing memory out of bounds and the fact that you haven't initialized any of the doubles.
What you need to do is call enterDouble for all indices:
for(int j = 0; j < dcount; ++i)
enterDouble(doubles, j);
And the dcount++; in enterDouble makes to me no sense, the caller knows which index it it passing, no need to returns the same index + 1.
Also see do not cast malloc and you are not freeing the memory you've
allocated.
Also the proper conversion specifier for reading doubles with scanf is %lf, not %f.
man scanf
...
l Indicates either that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a long int or
unsigned long in (rather than int), or that the conversion will be one of e, f, or g and the next pointer is a pointer to
double (rather than float).
...
f Matches an optionally signed floating-point number; the next pointer must be a pointer to float.

What is the good practice to declare loop variables?

In a block of code, I need to get an input from the user and print it right away. I'm a bit confused with good practice between these two snippets.
Snippet #1:
int i;
while(){
scanf("%d", &i);
printf("%d", i);
}
I'm using the variable i only within the loop. So, should I declare and use it within the loop itself to maintain good practice of using scopes?
If I do the same,
Snippet #2:
while(){
int i;
scanf("%d", &i);
printf("%d", i);
}
the variable i is declared on every iteration of the loop! These re-declarations consume more processing power and re-allocation of memory again and again
Which approach is better and why?
You said:
the variable i is declared on every iteration of the loop! These re-declarations consume more processing power and re-allocation of memory again and again
This is an invalid assumption on your part. The C compiler will calculate the total memory the function needs and allocate for that usage up front. For local variables, that allocation is actually just a shift of a pointer.
To illustrate, if I have a function:
void a_function () {
extern int x, n1, n2;
while (--n1) {
int i;
scanf("%d", &i);
x += i;
}
while (--n2) {
int i, j;
scanf("%d %d", &i, &j);
x += i + j;
}
}
The compiler will allocate space for 2 integers on entry into the function (or none, if it decides it can do everything in registers).

C writing into pointer array?

I have a homework that wants us to make an array of (x,y) coordinates that the user enters but we don't know how many will be entered, it will end when (0,0) is entered, the last one will not be added to the array and then we sort them and print them.So I used pointers to make array but I can't insert all the elements that I want to insert it only recognizes the last entered one. When I try to print them it will print only the last one I entered correctly the others mostly comes (0,0) or some random numbers.
int main()
{
int x,y,*xp,*yp;
int a = 0,s,m=12;
etiket:
scanf("%d %d",&x,&y);
printf("\n");
while (x != 0 || y != 0)
{
a=a+1;
xp = (int*) malloc(sizeof(int)*m);
yp = (int*) malloc(sizeof(int)*m);
//printf("%d %d\n",x,y);
if( a%10==0)
{
xp = (int*) realloc(xp,sizeof(int)*m+10);
yp = (int*) realloc(yp,sizeof(int)*m+10);
}
xp[a]=x;
yp[a]=y;
printf("%d %d\n",*(xp+a),*(yp+a));
goto etiket;
//SortPoints((xp+a),(yp+a),a);
}
//printf("siralama:\n");
//for(s=0; s<=a; s++)
//{
// printf("%d %d\n",*(xp+s),*(yp+s));
//}
}
So this is my work-in-progress code.
I don't even know if it's possible I would appreciate any help.
Thank you in advance.
As you have been restricted to use C it's lot easier to use structure for dynamically allocated memory for arrays. Here's the code:-
#include<stdio.h>
#include<malloc.h>
#define SIZE 20 // SIZE OF YOUR ARRAY FOR DYNAMIC MEMORY ALLOCATION
typedef struct {
int x;
int y; // That's the point with x and y coordinate
} point ; // Similar as int n, float a .... now point is a
// type which holds the value of x and y
int main(void){
point *p; // pointer decleration for point type
p= (point *)malloc(SIZE* sizeof(point)); // Memory Allocation
int i=0;
do{
p++; // increment of pointer
i++;
printf("Enter values for point %d: (x,y)= ",i);
scanf("%d", &p->x); // input x and y
scanf("%d", &p->y);
}while((p->x) !=0 || (p->y) !=0 ); // loop breaks when inputs 0,0
p--; // decrement pointer as 0,0 value will have no use
i--;
printf("\n\n\n");
for(;i>0;i--,p--)
printf("Point %d: (x,y)=(%d,%d)\n", i,p->x, p->y);
// displaying point values user given
printf("\n\n\n");
return 0;
}
Here p holds the hole array of points. Now, for sorting you just have to pass p in a function as a agrument like that and write the regular sorting algorithm inside the body.
point* SortingArray(point *p)
This function will return another arrays of points which is sorted. Hope you could do this yourself.
Furthermore, probably very soon You will learn C++ where this kind of works are so easy using class. In fact, in C++ there have a lot of features in the STL(Standard Template Library) like lists,vectors... for these kind of works which support dynamic memory allocation very soundly.
Let me know if You find any problem to grasp the concept. Thanks.

How can i add numbers to an array using scan f

I want to add numbers to an array using scanf
What did i do wrong? it says expected an expression on the first bracket { in front of i inside the scanf...
void addScores(int a[],int *counter){
int i=0;
printf("please enter your score..");
scanf_s("%i", a[*c] = {i});
}//end add scores
I suggest:
void addScores(int *a, int count){
int i;
for(i = 0; i < count; i++) {
printf("please enter your score..");
scanf("%d", a+i);
}
}
Usage:
int main() {
int scores[6];
addScores(scores, 6);
}
a+i is not friendly to newcomer.
I suggest
scanf("%d", &a[i]);
Your code suggests that you expect that your array will be dynamically resized; but that's not what happens in C. You have to create an array of the right size upfront. Assuming that you allocated enough memory in your array for all the scores you might want to collect, the following would work:
#include <stdio.h>
int addScores(int *a, int *count) {
return scanf("%d", &a[(*count)++]);
}
int main(void) {
int scores[100];
int sCount = 0;
int sumScore = 0;
printf("enter scores followed by <return>. To finish, type Q\n");
while(addScores(scores, &sCount)>0 && sCount < 100);
printf("total number of scores entered: %d\n", --sCount);
while(sCount >= 0) sumScore += scores[sCount--];
printf("The total score is %d\n", sumScore);
}
A few things to note:
The function addScores doesn't keep track of the total count: that variable is kept in the main program
A simple mechanism for end-of-input: if a letter is entered, scanf will not find a number and return a value of 0
Simple prompts to tell the user what to do are always an essential part of any program - even a simple five-liner.
There are more compact ways of writing certain expressions in the above - but in my experience, clarity ALWAYS trumps cleverness - and the compiler will typically optimize out any apparent redundancy. Thus - don't be afraid of extra parentheses to make sure you will get what you intended.
If you do need to dynamically increase the size of your array, look at realloc. It can be used in conjunction with malloc to create arrays of variable size. But it won't work if your initial array is declared as in the above code snippet.
Testing for a return value (of addScores, and thus effectively of scanf) >0 rather than !=0 catches the case where someone types ctrl-D ("EOF") to terminate input. Thanks #chux for the suggestion!

Resources