Fred Vann
Fred Vann

Reputation: 19

How do I alphabetically sort pointers to characters char** in C?

I am new to C. I made my own sorting to sort a bunch of strings alphabetically and this is what I have, but strcmp does not seem to work? The program just crashes.

int main(void) {
   char **a = malloc(sizeof(char*));
   a[0] = "Cam";
   a[1] = "Bam";
   a[3] = "Dam";
   a[4] = "Aam";
   for (int i = 0; a[i] != '\0'; i++) {
      for (int j = i+1; a[j] != '\0'; j++)
         if (strcmp(a[i], a[j]) > 0) {
            char* temp = a[i];
            a[i] = a[j];
            a[j] = temp;
         }
       printf("%s ", a[i]);
     }
   return 0;
}
// output should be Aam Baam Caam Daam

Upvotes: 0

Views: 651

Answers (3)

Daniel Walker
Daniel Walker

Reputation: 6760

You've only allocated enough size for a single pointer and yet you're assigning five pointers worth of space.

Try this:

char **a = malloc(sizeof(char*)*5);

Upvotes: 0

tadman
tadman

Reputation: 211700

There's a lot of confusion in this code about how C works, and a lot of simple mistakes that are avoided if care is taken to pay extremely close attention to the smallest details. In programming a single character can make a world of difference, a tiny slip can change the behaviour of your code dramatically, from working to broken, or from bug-free to completely trashed.

Here's a more idiomatic C version of your code:

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

int main(void) {
  // Create a local variable to represent the strings to be sorted
  char *a[] = {
    "E",
    "B",
    "C",
    "A",
    "D",
    NULL // Use NULL as a terminator
  };

  // Iterate over each entry and stop at the NULL terminator...
  for (int i = 0; a[i]; i++) {
    for (int j = i+1; a[j]; j++) {
      if (strcmp(a[i], a[j]) > 0) {
        char* temp = a[i];
        a[i] = a[j];
        a[j] = temp;
      }
    }
  }

  // Once the sort has wrapped, print the sorted array
  for (int i = 0; a[i]; i++) {
    // This was erroneously inside the sorting routine before
    printf("%s ", a[i]);
  }

  printf("\n");

  return 0;
}

Note, many simple mistakes can be caught using -Wall when compiling, or equivalent, where the compiler warns (-W) about everything (all) that it thinks is incorrect.

In clang you'd get warnings like:

sort.c:10:28: warning: comparing a pointer to a null character constant; did you mean to compare to NULL? [-Wpointer-compare]

This helps identify bugs early. Remember in C that "compiles" and "correct" are often worlds apart. A compiler doesn't check much in C other than syntax. The rest is on you, and as a C programmer you have a lot of responsibility.

Off-by-one errors, walking off the end of an array, and failing to allocate or free memory are just a few of the many things you need to keep in mind when writing C. This is a language designed to be fast, not safe. It's like a race car in that if you don't know how to drive it, you will spin out and go into a wall right away.

Take your time, get some good references, and learn from good examples. You can get the hang of C pretty quickly once you understand what it will and absolutely will not do for you.

Upvotes: 2

Bill Lynch
Bill Lynch

Reputation: 81986

Three issues:

  1. You have only allocated space for an array of length 1, but you used 5 slots. To allocate an array of size 5, use char **a = malloc(5 * sizeof(char *));

  2. You never initialized a[2].

  3. a[i] != '\0' doesn't make much sense since you're comparing a pointer to a char.

Upvotes: 3

Related Questions