简体   繁体   中英

stdlib.h qsort() on char array crashes in c

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

int cmpfunc(const void *a, const void *b) {
   const char *ia = (const char*)a;
   const char *ib = (const char*)b;
   return *ia - *ib;
}

int is_permutation(char *s1, char *s2){
    int i, n1, n2;


    n1 = sizeof(s1)/sizeof(s1[0]);
    n2 = sizeof(s2)/sizeof(s2[0]);


    if(n1 != n2){
        return 0;
    }


    qsort(s1, n1, sizeof(s1), cmpfunc);
    qsort(s2, n2, sizeof(s2), cmpfunc);

    for (i = 0; i < n1;  i++)
       if (s1[i] != s2[i])
         return 0;

    return 1;
}

int main(){
    char s1[5] = "check";
    char s2[5] = "check";

    printf("%d", is_permutation(s1,s2));

    return 0;
}

It just crashes with no compiler errors. I've checked and the qsort crashes the program, everything else seems to work appropriately. Any help?

I compile with "gcc -g -ansi -pedantic -Wall prog.c -o prog"

sizeof(s1) &c. is not a function of the number of elements in the array. This is because s1 has decayed to a pointer type.

strlen can be used to get the length of a string, but you'd need to write

char s1[6] = "check";

or better still,

char s1[] = "check";

to allow space for the NUL-terminator.

I've checked and the qsort crashes the program, everything else seems to work appropriately. ? No, have a run in debugger ? Try compiling with -g option and run gdb and do bt .

The problematic statement are

n1 = sizeof(s1)/sizeof(s1[0]); /* it will results in 4/1 that is 4 */
n2 = sizeof(s2)/sizeof(s2[0]);

Instead rotate loop inside s1 and find the length or use strlen() to find the length of s1 and s2 as

for(n1 = 0;s1[n1]!='\0'; n1++); /* dummy loop, at the end of loop, n1 will be length of s1 */
for(n2 = 0;s2[n2]!='\0'; n2++);

And

qsort(s1, n1, sizeof(s1[0]), cmpfunc);
qsort(s2, n2, sizeof(s2[0]), cmpfunc);

Here is the sample is_permutation() function

int is_permutation(char *s1, char *s2){
        int i, n1, n2;
        for(n1 = 0;s1[n1]!='\0'; n1++); /* dummy loop, at the end of loop, n1 will be length of s1 */
        for(n2 = 0;s2[n2]!='\0'; n2++);

        if(n1 != n2){
                return 0;
        }
        qsort(s1, n1, sizeof(s1[0]), cmpfunc);
        qsort(s2, n2, sizeof(s2[0]), cmpfunc);

        for (i = 0; i < n1;  i++)
                if (s1[i] != s2[i])
                        return 0;

        return 1;
}

Most importantly char s1[5]="check" doesn't have space for \\0 char. So either make char s1[6] or char s1[]= "check"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM