Hello guys!

I made a thread here a few days ago and got very good feedback. It helped alot but I have stumpled upon a new problem in the same program. This is quite much code (atleast for me, hehe), and I understand if you dont have time to look at it.

Anyway, the problem is that I have a list with a struct in each position. The struct contains four strings; artist, album, type and rating.

I need the user to be able to sort the list depending on one of these columns. For that I will use merge sort. This is the code for the list:

#ifndef _DLIST_H
#define _DLIST_H

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

#ifndef __DATA
#define __DATA
typedef void *data;

typedef void memFreeFunc(data);

typedef struct link {
    data data;
    struct link *next;
} element;

typedef element * dlist_position;

struct list {
    element *head;
    memFreeFunc *freeFunc;
typedef struct list dlist;

dlist *dlist_empty(void);

void dlist_setMemHandler(dlist *l, memFreeFunc *f);

dlist_position dlist_first(dlist *l);

dlist_position dlist_next(dlist *l,dlist_position p);

bool dlist_isEmpty(dlist *l);

dlist_position dlist_insert(dlist *l,dlist_position p,data d);

dlist_position dlist_remove(dlist *l, dlist_position p);

void dlist_free(dlist *l);

data dlist_inspect(dlist *l, dlist_position p);

bool dlist_isEnd(dlist *l, dlist_position p);

#include "dlist.h"

dlist *dlist_empty(void) {
    dlist *theList=malloc(sizeof(struct list));
    theList->head=malloc(sizeof(element)); //huvudet för listan
    return theList;

void dlist_setMemHandler(dlist *l, memFreeFunc *f) {

dlist_position dlist_first(dlist *l) {
   return l->head;

dlist_position dlist_next(dlist *l, dlist_position p) {
   return p->next;

bool dlist_isEmpty(dlist *l) {
    return (l->head->next==NULL);

dlist_position dlist_insert(dlist *l,dlist_position p,data d) {
   dlist_position newPosition=malloc(sizeof(element));
   return p;

data dlist_inspect(dlist *l, dlist_position p) {
    return p->next->data;

dlist_position dlist_remove(dlist *l,dlist_position p) {
   dlist_position temp=p->next;
   return p;

bool dlist_isEnd(dlist *l,dlist_position p) {
   return (p->next==NULL);

void dlist_free(dlist *l) {
   dlist_position p=dlist_first(l);
   while(!dlist_isEmpty(l)) {
   free (l->head);
   free (l);    
And here is the code which gives me trouble:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "dlist.h"
#define BUFSIZE 90

typedef struct {
        char artist[41];
        char album[41];
        char type[3];
        char rating[5];
} record;

void printMenu();
void readFile(FILE *infilep, dlist *list);
void printText(dlist *list);
dlist *mergeSort(dlist *list);
/*dlist *merge(dlist *list1, dlist *list2);*/

int main(int argc, char *argv[]) {

        int n;

        if(argc < 1) {
                fprintf(stderr, "Usage: %s <musik.txt>\n", argv[0]);

        /* Öppna filen */
        FILE * infilep;
        infilep = fopen(argv[1],"r");

        if (infilep == NULL) {
                fprintf(stderr, "Couldn't open input file.");

        /* Skapa listor och allokera minne */
        dlist *list=dlist_empty();

        /* Läs filen */
        readFile(infilep, list);

        /* Skriv ut meny */

        do {

                printf("\n\n Ange ditt val: ");

                switch (n) {
                case -1: printf("Programmet avslutas\n\n"); return 0; break;
                case 0: printMenu(); break;
                case 1: printText(list); break;
                case 2: mergeSort(list); break;
//              case 3: merge(list1, list2); break;
                default: printf("Ogiltigt val\n"); printMenu(); break;

        } while (n != -1);

        return 0;

Funktion: printMenu
Beskrivning: Skriver ut menyn för programmet.
Input: -
Output: -
void printMenu(void) {

        printf("0. Visa menyn\n");
        printf("1. Visa lista\n");
        printf("2. Sortera lista på artister\n");
        printf("3. Sortera lista på album\n");
        printf("4. Sortera lista på typ\n");
        printf("5. Sortera lista på betyg\n");
        printf("-1. Avsluta\n");


Funktion: readFile
Beskrivning: Läser in data från filen.
Input: Datastukturen record och filpekaren infilep.
Output: -a
void readFile(FILE *infilep, dlist *list) {

        char line[BUFSIZE];
        dlist_position pos;

        /*Läs in information från musik.txt och spara
          structs i listan */
        while (fgets(line, BUFSIZE, infilep) != NULL) {
                record *info = malloc(sizeof(record));
                sscanf(line, "%[^;];%[^;];%[^;];%s",
                info->artist, info->album,
                info->type, info->rating);
                pos = dlist_insert(list,pos,info);
                pos = dlist_next(list,pos);


Funktion: printText
Beskrivning: Skriver ut artist, album, typ och betyg
i kolumner på skärmen. Man kan välja att visa mer text.
Input: Riktad lista
Output: Utskriven text

void printText(dlist *list) {

        int n;
        dlist_position pos;
        pos = dlist_first(list);

        printf("\nAnge hur många rader du vill visa:");

        printf("\nARTIST                                  ALBUM                                   TYP

        /* Skriver ut det antal rader användaren bestämt */
        for(int i = 0; i < n; i++) {

                record *rcrd = (record*) dlist_inspect(list, pos);
                printf("%-40s%-40s%-2s %-4s\n", rcrd->artist, rcrd->album, rcrd->type, rcrd->rating);
                pos=dlist_next(list, pos);
                        if(dlist_isEnd(list, pos) == 1) {
                                printf("\n Listans slut.");


Funktion: mergeSort
Beskrivning: Delar upp den ursprungliga listan i två delar, där vartannat värde hamnar
i lista1, och vartannat i lista 2. Funktionen anropar sig själv så att två till listor skapas,
och slutar först när listorna bara har en position. Då skickas listorna vidare till
funktionen merge.
Input: Riktad lista
Output: Halverade listor
dlist *mergeSort(dlist *list) {

        dlist_position pos, pos1, pos2;

        /* Skapa två nya listor */
        dlist *list1 = dlist_empty();
        dlist *list2 = dlist_empty();

        /* Tag fram den första posititonen */
        pos = dlist_first(list);
        pos1 = dlist_first(list1);
        pos2 = dlist_first(list2);

        /* Allokera minne */
        record *rec = malloc(sizeof(record));

                /* Dela upp ursprungslistan i två nya listor */
                if(!dlist_isEnd(list, pos)) {

                        while(!dlist_isEmpty(list)) {

                                rec = (record*) dlist_inspect(list, pos);
                                dlist_remove(list, pos);
                                dlist_next(list, pos);

                                dlist_insert(list1, pos1, rec);
                                dlist_next(list1, pos1);

                                        if(!dlist_isEmpty(list)) {

                                                rec = (record*) dlist_inspect(list, pos);
                                                dlist_remove(list, pos);
                                                dlist_next(list, pos);

                                                dlist_insert(list2, pos2, rec);
                                                dlist_next(list2, pos2);


        /* Anropa mergeSort med de nya listorna */
        list1 = mergeSort(list1);
        list2 = mergeSort(list2);

        /* Anropa merge med listorna */
        merge(list1, list2);

        /* Returnera den sorterade listan */
The commenting is in swedish I'm afraid, but I hope you can get something out of it without the comments...

When I try to run the program it runs through the while-loop in mergeSort a few times but then I get a segmentation fault. I think it has to do with dlist_inspect trying to extract a struct when there is nothing to extract. But at the same time I thought I fixed that with the "!dlist_isEmpty(list)"...

Would love some help, if its possible.