Segmentation fault:11, when I run C code - c

I am new in C programming. When I write a c code about sorting integers. I got a Segmentation fault: 11. I search the related articles, but seems too confusing for me. Here follows first part of my code(get 10 input integers, and derive all the odd integers). Can you help me?
#include <stdio.h>
int i;
int main(void)
{
int array[10];
int previous[10],odd[10];
printf("Pls enter 10 nums\n");
while(i < 10)
{
scanf("%d", &array[i++]);
}
for(i = 0;i < 10;i++)
{
printf("%d ", array[i]);
}
for(i = 0;i < 10;i++)
{
int a,j;
if(array[i] % 2 == 1)
{
previous[a] = i;
odd[j] = array[i];
a++;
j++;
}
}
}

The problem is with the variables a and j. In C you cannot be sure that when you declare them they will have the value 0.

If you don't give i and a initial values you will likely be attempting to go beyond the bounds of your array.

Related

Finding out if the first digit of every number in an array is odd in C

So basically what my c program needs to do is find out if the first digit of a number is odd, and do so for every element of a 12- element array. Also I need to make the program in the manner that finding out if the first element of a single number is odd needs to be written in a special function outside of main(). This program is really easy to make only in main() but as far as I know you need to use pointers for an array if you want to do something with it outside of main() and I'm not really good at that tbh. So any help would do me a big favour I guess.
This is what I've done so far:
#include <stdio.h>
int function(int p[], int n)
{
int i;
int x;
for (i = 0; i < n; i++)
{
while (p[i] >= 10)
;
{
p[i] /= 10;
}
if (p[i] % 2 != 0)
{
x++;
}
}
return x;
}
int main()
{
int n = 12;
int array[n];
int i;
for (i = 0; i < n; i++)
{
scanf("%d", &array[i]);
}
int r;
r = function(array[n], n);
printf("%d", r);
return 0;
}
And this is what my apparent errors are:
main.c:31:22: warning:
passing argument 1 of ‘function’ makes pointer from integer without a cast [-Wint-conversion]
main.c:3:9: note: expected ‘int *’ but argument is of type ‘int’
So yeah as I said, any help would do good. Also keep in mind that I'm in the first year of the first semester of college and that we can't really use anything outside of <stdio.h> or <stdlib.h> to write our code.
No pointers needed, unless you want to modify the array passed.
Some issues:
while(p[i] >= 10);{
p[i] /= 10;
}
The above code runs in an infinite loop, after which it runs p[i] /= 10; once.
Most C programmers have issues with missing ;. You have the opposite problem: A ; where it shouldn't be.
To put it simply, that intruding ; tells the compiler that the while loop doesn't run any code, so the compiler actually thinks your code means this:
while(p[i] >= 10) {
// Do nothing
}
p[i] /= 10;
int r;
r = function(array[n], n);
printf("%d", r);
That r variable is pointless. Unless you don't want to directly pass the return value from function
If the value of n is 12 then array[n] is the 12th element of array. Which doesn't exist because array only has elements 0-11
This is how I would write the code if I wanted to pass the whole array to my function:
printf("%d", function(array, n));
Here is a working version of the code you want
#include <stdio.h>
int count_odd_fdigits();
int main() {
const int ARRAY_SIZE = 12;
int array[ARRAY_SIZE];
int i;
for (i=0; i < ARRAY_SIZE; i++) {
scanf("%d", &array[i]);
}
printf("Numbers with an odd first digit: %d", count_odd_fdigits(array, ARRAY_SIZE));
return(0);
}
int count_odd_fdigits(int numbers[], int limit) {
int i;
int count = 0;
for (i=0; i < limit; ++i) {
while (numbers[i]/10 > 0)
numbers[i] /= 10;
if (numbers[i] % 2 != 0)
++count;
}
return(count);
}
(Run it online: https://onlinegdb.com/yEPr_mYgna)

C program shows different result in Linux and online compiler

I wrote a program in C to arrange the data in ascending order. When I compiled the code it showed no error but when it runs it shows a very different result than expected. However, when I ran the code in online C compiler it shows the correct result. I entered 5 different numbers 2 ,3 ,1 ,5 ,4.
Result in Linux: 0 1 2 3 4
Result in online compiler: 1 2 3 4 5
Why is this happening?
#include<stdio.h>
int * array(int x[],int l){
int i,j,k;
for(i=0;i<l;i++){
for(j=0;j<l;j++){
if(x[j]>x[j+1]){
k=x[j];
x[j]=x[j+1];
x[j+1]=k;
}
}
}
return x;
}
void main(){
int i,n;
int *b;
printf("enter n\n");
scanf("%d",&n);
int a[n];
for(i=0;i<n;i++)
scanf("%d",&a[i]);
b=array(a,n);
printf("the ascending order is: ");
for(i=0;i<n;i++){
fflush(stdout);
printf("%d\t",b[i]);
}
}
Your code accesses memory beyond your array:
for(j=0;j<l;j++){
if (x[j] > x[j + 1]) {
x[j] = x[j + 1];
x[j + 1] = k;
In your case, when n = 5, you allocate the array for 5 elements with indices 0,1,2,3,4. The latest element of the array is x[4]. But when your code runs and j == l-1, you try to compare and even modify the element x[5]. In fact, your program should crash as it tries to access the "unallocated" memory. But probably because of aligning, the "x[5]" addresses the allocated memory. And, probably, x[5] = 0 on your computer, and your algorithm uses this element as a part of the sorting process. So your function array() returns the array of [0,1,2,3,4,5] and then your main() prints first five elements of this array.
That's why you've got sorted elements [0,1,2,3,4] instead of [1,2,3,4,5].
BTW, the bubble algorithm can be optimized to not touch already sorted elements.
Also, remember the array doesn't copy to pass into the function, the array always passes by its address, so it is not needed to "return" the modified array.
So, the final code can look like:
#include <stdio.h>
void array(int x[], int l)
{
int i, j, k;
for (i = l; i > 1; i--) {
for (j = 1; j < i; j++) {
if (x[j - 1] > x[j]) {
k = x[j - 1];
x[j - 1] = x[j];
x[j] = k;
}
}
}
}
void main()
{
int i, n;
printf("enter n\n");
scanf("%d", &n);
int a[n];
for (i = 0; i < n; i++)
scanf("%d",&a[i]);
array(a, n);
printf("the ascending order is:");
for (i = 0; i < n; i++) {
printf(" %d", a[i]);
fflush(stdout);
}
printf("\n");
}
Of course, there are lots of things to be done in this code, like human-readable variables, formatting, further optimization. But I hope you can do it yourself.
You may find it easier to write programs to get their input from the command line instead of prompting for it. Using C11, you can allocate an array using the length provided by argc, and process the argv array directly:
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[] ) {
if( argc == 1 ) {
errx(EXIT_FAILURE, "syntax: %s values...", argv[0]);
}
int a[argc - 1];
for( int i=0; i < argc-1; i++ ) {
if( 1 != sscanf(argv[i + 1], "%d", a + i) ) {
errx(EXIT_FAILURE, "could not scan '%s'", argv[i + 1]);
}
}
array(a, sizeof(a)/sizeof(a[0]));
printf("the ascending order is:");
for (i = 0; i < n; i++) {
printf(" %d", a[i]);
fflush(stdout);
}
printf("\n");
}

C Segmentation Fault While using scanf for 2D array

As suggested by a book of "Gottfried", I tried to input an array and display the contents of array in matrix form :
#include<stdio.h>
#define row 2
#define col 3
int main(){
int (*a)[col];
int i,j;
for(i=0;i<row;i++){
for(j=0;i<col;j++){
printf("Enter a(%d,%d)",i,j);
scanf("%d",(*(a+i)+j));
}
}
return 0;
}
I get the following output after inputting an element :
Segmentation fault (core dumped)
What is the problem in the code? Was it working in previous version of GCC so the writer wrote it down? What is the correct way to solve the problem with the same level of simplicity?
As it was pointed out in the comments it is not a 2D array, but a 1D array of pointers.
Also in the second for loop you accidently use i<col instead of j<col.
This will work
#include<stdio.h>
#define ROW 2
#define COL 3
int main(){
int a[ROW][COL];
int i, j;
for(i = 0; i < ROW; i++){
for(j = 0;j < COL; j++){
printf("Enter a(%d,%d)", i, j);
scanf("%d", (*(a + i ) + j));
}
}
return 0;
}
If you want to declare a as a pointer to an array of col ints, as it's done in this line
int (*a)[col];
Then you should also allocate (and ultimately free) the memory needed, before trying to use it.
a = malloc(sizeof(*a) * row);
if (!a)
exit(1);
// ...
free(a);
The posted code also have another issue in the nested loops
for (i = 0; i < row; i++) {
for (j = 0; i < col; j++) {
// ^^^^^^^ It should be 'j < col'

The monitored command dumped core?

Well on a regular basis i get obstructed with this error , the monitored command dumped core.
Which is pretty much alien language to me, hence i cannot not possibly understand what the compiler is saying.
I looked up the internet , for what could be the reason and found out that i could be accessing index which has not been allocated memory, therefore i set on to make a simplest code possible and encounter the same error.
#include<stdio.h>
int main()
{
int n;
int a[100000];
scanf("%d",&n);
int j=0;
for(int i=2;i<=n;i+2)
{
if (i%2==0)
{
a[j]=i;
j+=1;
}
}
return 0;
}
But i don't understand how i could be accessing non allocated memory.
Also what could be the other reasons for the same error to occur such frequently.
I think the issue could be your for loop, as in the third part you're not updating i. To update, write it as i=i+2 or i+=2.
Your index j gets out of bounds:
Demonstration:
#include<stdio.h>
int main()
{
int n;
int a[100000];
scanf("%d", &n);
int j = 0;
for (int i = 2; i <= n; i + 2)
{
if (i % 2 == 0)
{
if (j > 100000) // <<<<<<<<<<<<<<
{
printf("Bummer\n");
return 1;
}
a[j] = i;
j += 1;
}
}
return 0;
}
Accessing an array with out of bounds results undefined behaviour (google that term).
You are incrementing the value of i. You have written i+2 instead of i+=2.
#include<stdio.h>
int main()
{
int n;
int a[100000];
scanf("%d",&n);
int j=0;
for(int i=2;i<=n;i+=2)
{
if (i%2==0)
{
a[j]=i;
j+=1;
}
}
return 0;
}
You are writing i+2 ,but you have to write i+=2.

How to read space-separated integers representing the array's elements and sum them up in C

How to read space-separated integers representing the array's elements and sum them up in C?
I used the below code but it reads all the elements in a new line:
#include <math.h>
#include <stdio.h>
int main() {
int i = 0, N, sum = 0, ar[i];
scanf("%d" , &N);
for (i = 0; i < N; i++) {
scanf("%d", &ar[i]);
}
for (i = 0; i < N; i++) {
sum = sum + ar[i];
}
printf("%d\n", sum);
return 0;
}
Your array ar is defined with a size of 0: the code invokes undefined behavior if the user enters a non zero number for the number of items.
Furthermore, you should check the return value of scanf(): if the user enters something not recognized as a number, your program will invoke undefined behavior instead of failing gracefully.
Here is a corrected version:
#include <stdio.h>
int main(void) {
int i, N, sum;
if (scanf("%d", &N) != 1 || N <= 0) {
fprintf(stderr, "invalid number\n");
return 1;
}
int ar[N];
for (i = 0; i < N; i++) {
if (scanf("%d", &ar[i]) != 1) {
fprintf(stderr, "invalid or missing number for entry %d\n", i);
return 1;
}
}
sum = 0;
for (i = 0; i < N; i++) {
sum += ar[i];
}
printf("%d\n", sum);
return 0;
}
Note that the program will still fail for a sufficiently large value of N as there is no standard way to check if you are allocating too much data with automatic storage. It will invoke undefined behavior (aka stack overflow).
You should allocate the array with malloc() to avoid this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i, N, sum;
int *ar;
if (scanf("%d", &N) != 1 || N <= 0) {
fprintf(stderr, "invalid number\n");
return 1;
}
ar = malloc(sizeof(*ar) * N);
if (ar == NULL) {
fprintf(stderr, "cannot allocate array for %d items\n", N);
return 1;
}
for (i = 0; i < N; i++) {
if (scanf("%d", &ar[i]) != 1) {
fprintf(stderr, "invalid or missing number for entry %d\n", i);
return 1;
}
}
sum = 0;
for (i = 0; i < N; i++) {
sum += ar[i];
}
printf("%d\n", sum);
free(ar);
return 0;
}
Finally, there is still a possibility for undefined behavior if the sum of the numbers exceeds the range of type int. Very few programmers care to detect such errors, but it can be done this way:
#include <limits.h>
...
sum = 0;
for (i = 0; i < N; i++) {
if ((sum >= 0 && arr[i] > INT_MAX - sum)
|| (sum < 0 && arr[i] < INT_MIN - sum)) {
fprintf(stderr, "integer overflow for entry %d\n", i);
return 1;
}
sum += ar[i];
}
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
scanf("%d",&ar[i]);
for(i=0; i<N; i++)
sum=sum+ar[i];
printf("%d\n", sum);
return 0;
}
This should be the code.
You have initially declared the array of size 0 (because i=0).
Even though you declared the array of size 0, when I ran it on my machine, it actually executed successfully with the correct output.
This is generally due to undefined behavior which means that we can only guess the output when the code is correct. If the code has undefined behavior, then it can do whatever it wants (and in the worst case the code will execute successfully giving the impression that it's actually correct).
Declaring a Variable Size Array (VLA) is optional in C11 standard. Thus, it depends on the implementation of the compiler whether it will support VLA or not. As pointed out by #DavidBowling in comments, if the compiler does support, then declaring a VLA of size 0 can invoke undefined behavior (which you should avoid in all cases). If it doesn't support, then this will simply give a compilation error and you'll have to declare the array size as some integer constant (example, int arr[100];).
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
{
scanf("%d",&ar[i]);
}
for(i=0; i<N; i++)
{
sum=sum+ar[i];
}
printf("%d\n", sum);
return 0;
}
You should declare the array after accepting the value of N.
#include <math.h>
#include <stdio.h>
int main()
{
int i=0,N,sum=0;
scanf("%d" ,&N);
int ar[N];
for(i=0; i<N; i++)
{
scanf("%d",&ar[i]);
sum=sum+ar[i];
}
printf("%d\n", sum);
return 0;
}
As this is a very simple question I'll expand it a bit to include some good programming practices.
1. Analyze the problem
We have to complete two tasks here:
Read and store the numbers to array.
Sum the array elements.
Of course you can both read and calculate the same time, but we ❤ the SoC design principle. This will help you later with bigger programs.
2. Create the program structure
In this state we have to consider what function to use, as we already solved the data structure problem (we use array).
Of course, we always can put the whole procedure in main function but this would break the SoC principle.
The main principle here is:
I create a function for a separate procedure.
So we'll have to build two functions. Let's consider the following example:
ReadArrayData will be used to read the data from the standard input (your keyboard in other words) to array. But what will declare as parameters? We surely have to pass the array and the array size. The return type of this function will be void (we don't have to return something).
Keep in mind that if you pass array to function you can manipulate it as you please and keep these changes in your main program. This is because the arrays are passed always by reference to a function.
In the end this will be your function prototype:
void ReadArrayData(int arraySize, int array[]);
CalculateArraySum will be used to calculate the sum of the array elements. The function prototype will be the same as for ReadArrayData with the difference that the returning type will be int (we return the sum).
int CalculateArraySum(int arraySize, int array[]);
3. Write your program
#include <stdio.h>
void ReadArrayData(int arraySize, int array[]);
int CalculateArraySum(int arraySize, int array[]);
int main(void) {
int N;
printf("Give the array size: ");
scanf("%d", &N);
int array[N];
ReadArrayData(N, array);
int sumOfArrayElements = CalculateArraySum(N, array);
printf("The sum of array elements is %d.\n", sumOfArrayElements);
return 0;
}
void ReadArrayData(int arraySize, int array[]) {
printf("Give %d elements: ", arraySize);
for (int i = 0; i < arraySize; ++i) {
scanf("%d", &array[i]);
}
}
int CalculateArraySum(int arraySize, int array[]) {
int sum = 0;
for (int i = 0; i < arraySize; ++i) {
sum += array[i];
}
return sum;
}
I know this was a large scaled answer, but I saw you are new to computer programing. I just wanted to present you the main functionality to solve all kinds of problems. This was just a small introduction. In the end, you have to remember what steps we take to solve a problem. With time and as you solve many problems you will learn many many other things.

Resources