I try to write a program which reads in single signs from a keyboard. If they are not already present they should be stored in a array.
After that, all signs get sorted and all already occurring signs are printed.
edit: if the entered sign already exists it is not added. The array should only contain unique elements.
The array starts with a size of 0 and should double its capacity every time it is full when a new character arrives.
Unfortunately it doesn't seem to work correctly. If I look via the debugger it looks like the values get stored one after another, but as soon as the second sign arrives the program crashes in print / qsort.
Am I doing something wrong in the allocation?
Also if you have other recommendations for improve this code please let me know.
#include <stdio.h>
#include <stdlib.h>
void reserve_space(char **c, int *capacity);
void print_signs(char **signs, const int max_size);
int cmp(void const *lhs, void const *rhs);
// allocates factor 2 of the current capacity
void reserve_space(char **c, int *capacity) {
char *new_c;
if (*capacity == 0) { // allocate the first time
*capacity = 1;
*c = malloc(sizeof(char) * ((*capacity)));
} else {
*capacity *= 2; // double the new capacity
new_c = realloc(*c, sizeof(char) * (*capacity));
*c = new_c;
}
return;
}
void print_signs(char **signs, const int sz) {
int i = 0;
for (i = 0; i < sz; ++i) {
printf("%i %c\n", *signs[i], *signs[i]); // crash in read after array has 2 signs???
}
printf("\n");
}
int cmp(void const *lhs, void const *rhs) {
char left = *((char *)lhs);
char right = *((char *)rhs);
if (left < right) return -1;
if (left > right) return 1;
return 0; /* left == right */
}
int main() {
int capacity = 0; // allocated space
int sz = 0; // space currently "filled" with signs
char *signs = 0;
char ch = 0;
int pos = 0;
while ((ch = getc(stdin)) != EOF) {
int pos = 0;
if (sz == capacity)
reserve_space(&signs, &capacity);
for (pos = 0; pos < sz; ++pos) {
if (signs[pos] == ch)
continue; /* indicating element exists already */
}
if (pos == capacity - 1) // -1 because last sign must be terminating '\0'
reserve_space(&signs, &capacity);
signs[pos] = ch; //adding new sign at pos of "old" \0
++sz;
++pos;
signs[pos] = '\0'; //adding new terminating \0
qsort(&signs, sz - 1, sizeof(char), cmp);
print_signs(&signs, sz);
}
getchar();
}
\0' to++sz, you have written to bad memory. You need to track the\0character in your size for the array.qsort(&signs, sz-1, sizeof(char), cmp);is suspicious, I'd expectqsort(signs, ...