I'm reading Brian W Kernighan and Dennis M Ritchie The C Programming Language, 2nd Edn and practicing using function pointers. I've implemented one of the examples from the book. I kept getting a segfault when addressing some of the functions.
After stepping through it with gdb I realized that when passing a function address to a pointer the pointer remained null, but only for some of the functions. Adding the & operator to the function names causing the error fixed the issue.
I've read everywhere that functions can be addressed by their name with or without the & operator. I cannot figure out why these functions required it. Or could it have something to do with the way I was assigning it?
EDIT: I understand the code is quite buggy. I was just doing a quick exercise from an old book. I will work on minimizing it. I'm just confused why when I step through the program with gdb fp remains null (without the &)after the assignment on lines 20 and 25 while on lines 27 and 29 fp does take get assigned the addresses.
  #include <stdio.h>
  #include <string.h>
   
  #define MAXLINES 5000
  char *lineptr [MAXLINES];
   
  int readlines(char *lineptr[], int nlines);
  void writelines(char *lineptr[], int nlines);
   
  void my_qsort(void *lineptr[], int left, int right, int (*comp)(void *, void *));
  int numcmp(char *, char *);
  int reva(char *, char *);
  int revn(char *, char *);
  
  
  int main(int argc, char **argv) {
  
          int nlines;
          int numeric = 0;
          int (*fp)(void*, void*) = &strcmp;
  
          if(argc > 1) {
                  for(int i = argc; i > 1; i--) {
                          if(strcmp(argv[i-1], "-n") == 0)
                                  fp = &numcmp;
                          else if(strcmp(argv[i-1], "-r") == 0)
                                  fp = reva;
                          else if(strcmp(argv[i-1], "-rn") == 0 || strcmp(argv[i-1], "-nr") == 0)
                                  fp = revn;
                          else {
                                  printf("error: invalid modifier [%s]\n", argv[i-1]);
                                  return -1;
                          }
                  }
          }
          if((nlines = readlines(lineptr, MAXLINES)) >= 0) {
                  my_qsort((void **) lineptr, 0, nlines-1, fp);
                  writelines(lineptr, nlines);
                  return 0;
          } else {
                  printf("input too big to sort\n");
                  return 1;
          }
  }
  
  
  void my_qsort(void *v[], int left, int right, int (*comp)(void *, void *)) {
  
          int i, last;
          void swap(void *[], int, int);
  
          if (left >= right)
                  return;
          swap(v, left, (left+right)/2);
          last = left;
          for(i = left+1; i <= right; i++)
                  if((*comp)(v[i], v[left]) < 0)
                          swap(v, ++last, i);
          swap(v, left, last);
          my_qsort(v, left, last-1, comp);
          my_qsort(v, last+1, right, comp);
  
  }
  
  
  #include <stdlib.h>
  
  int numcmp(char *s1, char *s2) {
  
          double v1, v2;
  
          v1 = atof(s1);
          v2 = atof(s2);
          if(v1 < v2)
                  return -1;
          else if(v1 > v2)
                  return 1;
          else
                  return 0;
  }
  
  
  int reva(char *s1,char *s2) {
          return -strcmp(s1, s2);
  }
  
  
  int revn(char *s1, char *s2) {
          return -numcmp(s1, s2);
  }
  
  void swap(void *v[], int i, int j) {
  
          void *temp;
  
          temp = v[i];
          v[i] = v[j];
          v[j] = temp;
  }
lines.c
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "get_line.h"
#define MAXLEN 1000 // max length of any input line
char *alloc(int);
// readlines: read input lines
int readlines(char *lineptr[], int maxlines) {
        int len, nlines;
        char line[MAXLEN];
        char lines[maxlines*MAXLEN];
        char *plines = lines;
        nlines = 0;
        while((len = get_line(line, MAXLEN)) > 0)
                if(nlines >= maxlines)
                        return -1;
                else {
                        line[len-1] = '\0'; // delete newline
                        strcpy(plines, line);
                        lineptr[nlines++] = plines;
                        plines += len;
                }
        return nlines;
}
// writelines: write output lines
void writelines(char *lineptr[], int nlines) {
        int i;
        for(i = 0; i < nlines; i++)
                printf("%s\n", lineptr[i]);
}
get_line.c
#include <stdio.h>
#include "get_line.h"
//getline: get line into line[]; return length
int get_line(char line[], int lim) {
        int c, i;
        i = 0;
        while(--lim > 0 && (c = getchar()) != EOF && c != '\n') {
                line[i++] = c;
        }
        if(c == '\n') {
                line[i++] = c;
        }
        line[i] = '\0';
        return i;
}
