Home > OS >  Segmentation fault in C program using pointers as parameters
Segmentation fault in C program using pointers as parameters

Time:02-11

Im trying to understand pointers as function parameters, and in one of the programs there is a segmentation error I can't fix. Firstly, why to use pointers in function arguments? and Why is this error showing?

#include <stdio.h>

void square_it(int* a)
{
  printf("The final value is: %d\n", *a * *a);
}

int main()
{
  int* input;

  puts("This program squares the input integer number");
  puts("Please put the number:");

  scanf("%d", &input);

  square_it(input);
  return 0;
}

CodePudding user response:

This is the working code:

#include <stdio.h>

void square_it(int* a)
{
  printf("The final value is: %d\n", *a * *a);
}

int main()
{
  int i = 0;
  int* input = &i;

  puts("This program squares the input integer number");
  puts("Please put the number:");

  scanf("%d", input);

  square_it(input);
  return 0;
}

There are some errors in the original code:

According to the man-pages to scanf, it takes a format string and then the address of where to store the input.

You gave it the address of a pointer (eg. an int**), which is not what scanf expects.

Also you need to provide memory to store the input in. The scanf string tells that you want an integer as input. In the above code snippet that is i.

input points to i, so i can give the int*, that is input to scanf. scanf will then write into i. We can then go ahead and put the address of i into the sqare_it function.

Since we did not use the heap, we don't need to worry about memory management.

CodePudding user response:

int* input; does not allocate memory for an int. It mearly makes it possible to make input point at an int (allocated elsewhere). Currently, by dereferencing it (like you do with *a), you make your program have undefined behavior. If you really want an intermediate pointer variable for this, this example shows how it could be done:

#include <stdio.h>

void square_it(int *a) {
    *a *= *a;     // same as  *a = *a * *a;
}

int main() {
    int data;
    int* input = &data; // now `input` points at an  `int`

    puts("This program squares the input integer number");
    puts("Please put the number:");

    // check that `scanf` succeeds:
    if(scanf("%d", input) == 1) { // don't take its address, it's a pointer already
        square_it(input);
        // since `input` is pointing at `data`, it's actually the value of `data`
        // that is affected by `scanf` and `square_it`, which makes the below work:
        printf("The final value is: %d\n", data);
    }
}

Without an intermediate pointer variable:

#include <stdio.h>

void square_it(int *a) {
    *a *= *a;
}

int main() {
    int input; // note that it's not a pointer here

    puts("This program squares the input integer number");
    puts("Please put the number:");

    if(scanf("%d", &input) == 1) { // here, taking the address of `input` makes sense
        square_it(&input);         // and here too
        printf("The final value is: %d\n", input);
    }
}

Without any pointers at all, it could look like this:

#include <stdio.h>

int square_it(int a) {
    return a * a;
}

int main() {
    int input;

    puts("This program squares the input integer number");
    puts("Please put the number:");

    if(scanf("%d", &input) == 1) { // here, taking the address of `input` makes sense
        int result = square_it(input);
        printf("The final value is: %d\n", result);
    }
}
  •  Tags:  
  • c
  • Related