1

In the standard qsort() function declared in <stdlib.h>, it crashes when I do the following:

char *arr[]={"abc","def"};
qsort((void*)arr[i],strlen(arr[i]),sizeof(char),compare);

For it to work, I have to use it like this:

int len=strlen(arr[i]);
char *buffer=new char[len+1];
strcpy(buffer, arr[i]);        
qsort((void*)buffer,strlen(arr[i]),sizeof(char),compare);

Why is the first method not working when the declaration of qsort() also specifies void* as its first argument?

I know that in the first method, what I am passing is not an array, but isn't char* always treated as an array?

If not, then what are the cases when it's not treated as an array?

JNYRanger
  • 6,829
  • 12
  • 53
  • 81
Diffy
  • 2,339
  • 3
  • 25
  • 47
  • char* is always treated as char*, its just that there is no real support for strings in C, so they settled on char* representing string. Also, your question is marked as C++, so please consider using std::string and std::sort instead – Creris May 06 '15 at 12:14
  • You don't need to cast *to* `void *` and second parameter is *quantity to sort* (so should be 2 and not 3). – crashmstr May 06 '15 at 12:40
  • @Creris: That's not quite true. C does support strings; there's just no data type called `string`. A string is by definition "a contiguous sequence of characters terminated by and including the first null character". A `char*` is not a string, though it may point to a string. – Keith Thompson May 08 '15 at 00:18

1 Answers1

3

The elements of the array arr are non-const pointers to string constants. Trying to modify what they point to (i.e. the string constant) via qsort() yields undefined behaviour. This is different from the scenario char p[] = "some string";, in which case you initialize the array p with the content of the string literal, then you can modify p with no problems. The correct definition of char* arr[] should be const char* arr[], precisely to prevent these kind of issues.

If you compile with all warnings on and with a C++ compiler you should get an warning similar to

warning: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic]

A plain C compiler seem to emit no warnings, but it is still undefined behaviour.

Closely related: Why do I get a segmentation fault when writing to a string initialized with "char *s" but not "char s[]"? and Modifying C string constants?

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252