C 语言初学这,请教字符串排序问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
chenqh
0D
V2EX    Linux

C 语言初学这,请教字符串排序问题

  •  
  •   chenqh 2018-12-24 18:44:05 +08:00 2909 次点击
    这是一个创建于 2484 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码

    #include <string.h> #include <stdio.h> #include <stdlib.h> int myCompare (const void * a, const void * b ) { const char *pa = *(const char**)a; const char *pb = *(const char**)b; return strcmp(pa,pb); } int main() { int i; // const char *input[] = {"a","orange","apple","mobile","car"}; const char *input[1024]; input[0]="a"; input[1] = "orange"; input[2] = "apple"; input[3] = "apple"; input[4] = "mobile"; input[5] = "car"; int stringLen = sizeof(input) / sizeof(char *); qsort(input, stringLen, sizeof(char *), myCompare); for (i=0; i<stringLen; ++i) printf("%d: %s\n", i, input[i]); } 

    这段代码为什么会报 coredump
    但是如果把input变成const char *input[] = {"a","orange","apple","mobile","car"};,那么就不会报错,求指点!!

    第 1 条附言    2018-12-24 19:28:45 +08:00
    解决了
    ```
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>

    int myCompare (const void * a, const void * b ) {
    const char *pa = *(const char**)a;
    const char *pb = *(const char**)b;

    return strcmp(pa,pb);
    }

    int main() {
    int i;
    // const char *input[] = {"a","orange","apple","mobile","car"};
    const char *input[1024];
    input[0]="a";
    input[1] = "orange";
    input[2] = "apple";
    input[3] = "apple";
    input[4] = "mobile";
    input[5] = "car";
    int stringLen = sizeof(input) / sizeof(char *);
    printf("stringLen:%d\n", stringLen);
    // qsort(input, 6, sizeof(char *), myCompare);

    for (i=0; i<6; ++i)
    printf("%d: %s\n", i, input[i]);
    }
    ```
    22 条回复    2018-12-26 13:48:15 +08:00
    littlewing
        1
    littlewing  
       2018-12-24 19:05:34 +08:00
    指针都没 malloc 不 core 才怪,先吧指针数组和数组指针弄清楚吧
    May725
        2
    May725  
    &nsp;  2018-12-24 19:19:26 +08:00 via iPhone
    记住一点,程序崩溃与内存有关,在 c 语言上可以联想到指针错误,所以要查查指针相关的调用。楼上也直接回答了原因
    Nasei
        3
    Nasei  
       2018-12-24 19:22:38 +08:00   1
    1024 这么大的数组, 你就给了 6 个值, 然后 stringLen 就错了
    chenqh
        4
    chenqh  
    OP
       2018-12-24 19:25:14 +08:00
    @Nasei 但是 stringLen 这句没有报错
    sl0000
        5
    sl0000  
       2018-12-24 20:55:36 +08:00   1
    1024 - 6 后面的 char * 都是 0x0, 但是 strcmp 的参数不能为 NULL
    2exploring
        6
    2exploring  
       2018-12-24 21:23:51 +08:00
    一二楼都指出问题在哪儿了,三楼和五楼都还没抓住问题的本质?
    sl0000
        7
    sl0000  
       2018-12-24 21:27:54 +08:00
    2exploring 什么本质?
    sl0000
        8
    sl0000  
       2018-12-24 21:28:40 +08:00
    zhuangzhuang1988
        9
    zhuangzhuang1988  
       2018-12-24 21:40:18 +08:00   1

    好好的用 IDE 看就知道
    xi2008wang
        10
    xi2008wang  
       2018-12-24 21:51:07 +08:00 via iPhone
    大型打脸现场
    2exploring
        11
    2exploring  
       2018-12-24 21:59:25 +08:00
    @sl0000 我收回上面说的话……
    一开始看一楼说 malloc 我就认为应该给 input malloc,其实不应该,是我大意了……
    三楼说的很对,不过你说的有点问题,其它位置的值不一定为 null,而是任何值都有可能。
    sl0000
        12
    sl0000  
       2018-12-24 22:06:44 +08:00
    接受! @2exploring

    大型科普现场:
    字符串 定义是从以第一个字节往后到'\0'为止.
    const char *input[] = {"a","orange","apple","mobile","car"}; 这种写法, 会把后面的空白元素都初始化 0x0 或者 0xcc...(这个指针大小也是不固定的).
    const char *input[1024]; 这种不会初始化;
    sl0000
        13
    sl0000  
       2018-12-24 22:14:44 +08:00
    额, const char *input[] = {"a","orange","apple","mobile","car"}; 这种写法元素就是 5 个.
    上面应该说的是 const char *input[1024] = {"a","orange","apple","mobile","car"};
    为什么不能重新编辑!!
    tmy
        14
    tmy  
       2018-12-25 09:51:58 +08:00
    const char *input[] = {"a","orange","apple","mobile","car"}这里 input 表示有 5 个指针的指针数组
    const char *input[1024];
    input[0]="a";
    input[1] = "orange";
    input[2] = "apple";
    input[3] = "apple";
    input[4] = "mobile";
    input[5] = "car";这个表示 input 是一个有 1024 个指针的指针数组,前面 6 个有明确的指针,后面的指针是野指针,那么在你的比较函数里面 strcmp 用到了野指针,结果可能崩溃也可能不崩溃,你改为 for (i=0; i<6; ++i)这个后没有使用到野指针也就不会崩溃
    aa514758835
        15
    aa514758835  
       2018-12-25 09:58:56 +08:00
    你得先知道 const char *input[1024]; 这句话是什么意思,你定义了一个指针数组,是一个数组,内容全是空指针。你需要为指针 malloc 空间才可以往里面存值。如果你改为 const char input[1024]; 此时
    aa514758835
        16
    aa514758835  
       2018-12-25 09:59:35 +08:00
    @aa514758835 摁了个回车居然自动发出去了,我话还没说完呢。 此时是一个数组,开在了栈上,所以直接可以赋值,不会报错
    stebest
        17
    stebest  
       2018-12-25 13:32:17 +08:00
    确实是一各初学问题,然而楼上的大佬们都互相打脸 2333。
    一楼的前半句就是对的,指针用多少写多少,申请那么多不给空间不初始化就调用,谁受得了。
    但并不是指针数组和数组指针的区别。
    2exploring
        18
    2exploring  
       2018-12-25 22:56:24 +08:00
    @aa514758835 const char *input[1024] 是一个指针数组你说对了,但内容并不全是空指针,也不是一定需要 malloc 才可以使用,只要给一个合法的指针值给它就可以用,比如 input[0] = "a","a" 就是一个合法的指针。楼主原始代码的问题在于没有确保 input[6..1023] 内容是合法的指针就使用了它们。至于你说的改为 const char input[2014],这还是原本的意思吗?还能完成原本的功能吗?
    chenqh
        19
    chenqh  
    OP
       2018-12-26 00:25:41 +08:00
    @2exploring 因为一开始不知道 input 到底有多大,所以给个 1024 的值,这是为了模拟
    aa514758835
        20
    aa514758835  
       2018-12-26 09:31:16 +08:00
    @2exploring 至于不 malloc 也能用的话,我以前是可以的,但是自从 vs 升到 2017 后,不开空间赋值就会报错了,估计其他编译器没事吧。最后那个 const char input[2014] 我确实说错了,忘了有 const,蛋疼
    2exploring
        21
    2exploring  
       2018-12-26 13:40:02 +08:00
    @aa514758835 你在 20 楼中的编译报错是因为你把一个 const char* 类型赋给了 char* 类型,这在 C++ 中是不被允许的( C 好像没有此限制,你的源文件后缀是 cpp,想必是 c++ 了),并不能说明不 malloc 就不能用,你好好看一下编译器给的错误信息。
    还有你说的改为 const char input[1024] 这个的问题也不在 const,而是你不明不白地把一个指针数组改为了 char 数组,我不知道你要怎么去使用这个 input ?
    aa514758835
        22
    aa514758835  
       2018-12-26 13:48:15 +08:00
    @2exploring 看来我还得再多了解一下......
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2691 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 14:50 PVG 22:50 LAX 07:50 JFK 10:50
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86