-3

I am writing my code chunk by chunk and trying to use pointer arithmetic in the process. My code calls a function and then is suppose to ask the user for 8 numbers. This then stores the numbers into the array using pointers. My problem is that I run into a segmentation fault. I believe the issue has to do with my pointer and the addresses. The chunk of code I think is causing this issue is scanf("%lf", *(coeff+1));. Is this the area that is throwing the fault and if so, what is the way to fix this?

#include <stdio.h>

void get_poly(double *coeff){

  int p;

  printf("Enter the eight coefficients: ");
    for(p = 0; p < 7; p++){
      scanf("%lf", *(coeff+1));
    }
}

int main(void){

  int i;
  double coeff[7];

  get_poly(coeff);

  printf("output");
    for(i = 0; i < 7; i++){
      printf("%lf",coeff[i]);
   }  
  return 0;
}
SgtOVERKILL
  • 309
  • 3
  • 11
  • There are multiple issues in the code. First, you should pass address to scanf. here you're passing a value. Second flaw is in logic. You're always passing the address(after you correct as discussed earlier) of the first slot. – Green goblin Jun 26 '16 at 18:09
  • 3
    `scanf("%lf", *(coeff+1));` --> `scanf("%lf", coeff+p);` – BLUEPIXY Jun 26 '16 at 18:17
  • 2
    Turn on compiler warnings, usually with `-Wall`. They point exactly at the problem. Passing in an already allocated pointer to `get_poly` is an unnecessary complication. The caller needs to do the allocation and needs to know how many numbers `get_poly` will read. You're better off letting `get_poly` allocate the memory itself and return a `double *`. Then you can use the argument to say how many numbers to read. – Schwern Jun 26 '16 at 18:22

3 Answers3

1
  scanf("%lf", *(coeff+1));

here, you are sending argument of wrong type into the scanf() function because *(coeff+1) is of the type double while the scanf() expects a pointer to double i.e, double* type argument.

Solution : drop the *(dereferencing) operator


for(p = 0; p < 7; p++)
{
  scanf("%lf", coeff+1);
}

gives no errors but it only populates the 2nd i.e, coef[1] element over each and every iteration.. instead you can use p to populate whole array

for(p = 0; p < 7; p++)
{
  scanf("%lf", coeff+p);
}
Cherubim
  • 5,287
  • 3
  • 20
  • 37
0

With compiler warnings on, the problem is clear.

$ make
cc -Wall -g    test.c   -o test
test.c:9:20: warning: format specifies type 'double *' but the argument has type 'double' [-Wformat]
      scanf("%lf", *(coeff+1));
             ~~~   ^~~~~~~~~~
1 warning generated.

scanf wants a double pointer, but it's being fed a double value.

What you're trying to do is increment coeff through the loop to simulate coeff[p]. What *(coeff+1) is actually doing is getting the value pointed at by coeff and adding 1 to it. This is similar to coeff[0] + 1. scanf treats this number (which will be gibberish) as a memory address and the program crashes.

What you want is to increment the pointer itself. But not by 1, coeff + 1 is similar to coeff[1]. Instead use p: coeff + p.


You also have the same off-by-one error twice. Your for loops are only iterating 7 times.

for(i = 0; i < 7; i++) {
               ^

That will go from 0 to 6. An easy rule of thumb is if you want to iterate N times you put i < N. This works because arrays are 0 indexed.


As far as how get_poly is designed, here's little reason to require that the user passes in an already allocated pointer. This requires the user to do extra work, and to know how many elements get_poly will read. If get_poly wants to read more, all the code calling it will break.

Instead, have get_poly do the allocation. Then you can also use the argument to ask how many numbers it should read. This makes the function safer and more flexible.

As a final touch, I've consistently used i for the for loop iterator. It's a standard convention, using p (for polynomial?) obscures that it's just a loop iterator (and it's not even counting polynomials).

#include <stdio.h>
#include <stdlib.h>

double *get_poly(int num_coeffs){
  int i;
  double *coeffs = calloc(num_coeffs, sizeof(double*));

  printf("Enter the %d coefficients: ", num_coeffs);
  for(i = 0; i < num_coeffs; i++){
      scanf("%lf", coeffs + i);
  }

  return coeffs;
}

int main(void){
  int i;

  double *coeffs = get_poly(8);

  printf("output: ");

  for(i = 0; i < 8; i++){
      printf("%lf ",coeffs[i]);
  }

  printf("\n");

  return 0;
}

And you should avoid scanf and instead use fgets + sscanf for all the reasons outlined here. I leave that as an exercise.

Community
  • 1
  • 1
Schwern
  • 153,029
  • 25
  • 195
  • 336
-1

The answer to this solution is as follows and provided by @BLUEPIXY

scanf("%lf", *(coeff+1)); --> scanf("%lf", coeff+p);
SgtOVERKILL
  • 309
  • 3
  • 11
  • Hi and welcome to Stack Overflow! While this is the correct code, to be a good answer it needs an explanation. Without the explanation, they won't understand what was wrong and how to avoid it in the future. Yes, even if you're answering your own question. :) – Schwern Jun 26 '16 at 18:40