Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数通过c中的多个分隔符将字符串拆分为数组_C_Memory Management - Fatal编程技术网

函数通过c中的多个分隔符将字符串拆分为数组

函数通过c中的多个分隔符将字符串拆分为数组,c,memory-management,C,Memory Management,编辑:感谢@R Sahu在我的例程中找到了bug。对于感兴趣的读者,以下是更正的代码: #include <stdio.h> #include <string.h> #include <stdlib.h> int str_split(char **array, char *buf, char *sep, int max){ char *token; int i = 0; int

编辑:感谢@R Sahu在我的例程中找到了bug。对于感兴趣的读者,以下是更正的代码:

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

    int str_split(char **array, char *buf, char *sep, int max){
        char *token;
        int i = 0;
        int size = 0;
        char *bp = strdup(buf);
        while ( ( i < max -1 ) && ((token = strsep(&bp,sep))!= NULL ) ) {
            array[i++] = token;
        }
        array[i] = NULL;  // set to null
        size = i;
        return size;
    }

    main(){
        char buf[100];
        strcpy(buf,  "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35");
        char *array[50];
        char sep[] = "*,";
        int number =  str_split(array, buf+1, sep, 50);  // number is number of elements in array
        int i;
        for (i = 0; array[i] != NULL; i++) printf("%s\n",array[i]);
        free (array[0]);
        return 0;
    }
当我改成这个的时候

while ( (i< 5) &&  ((token = strsep(&bp,sep))!= NULL ) ) {
在我写这篇文章的时候,我突然想到我只需要测试I>max并跳过对数组的赋值。成功了

我修改的代码是:

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

int str_split(char **array, char *buf, char *sep, int max){
        char *token;
        int i = 0;
        int size = 0;
        char *bp = strdup(buf);
        while (  ((token = strsep(&bp,sep))!= NULL ) ) {
                if (i < max ) array[i++] = token;
        }
        i = (i > max)? max : i; 
        array[i] = NULL;  // set to null
        size = i;
        free(bp);

    return size;
}

main(){
    char buf[100];
        strcpy(buf,  "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35");
        char *array[50];
    char sep[] = "*,";
  int number =  str_split(array, buf+1, sep, 5);  // number is number of elements in array
    int i;
        for (i = 0; array[i] != NULL; i++) printf("%s\n",array[i]);
return 0;
}
#包括
#包括
#包括
int str_split(字符**数组、字符*buf、字符*sep、int max){
字符*令牌;
int i=0;
int size=0;
char*bp=strdup(buf);
while((令牌=strep(&bp,sep))!=NULL)){
如果(imax)?max:i;
数组[i]=NULL;//设置为NULL
尺寸=i;
自由基(bp);
返回大小;
}
main(){
char-buf[100];
strcpy(buf,“$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,,,,,,1.7,1.0,1.3*35”);
字符*数组[50];
字符sep[]=“*,”;
int number=str_split(数组,buf+1,sep,5);//number是数组中的元素数
int i;
对于(i=0;数组[i]!=NULL;i++)printf(“%s\n”,数组[i]);
返回0;
}
我想知道的是

1) 是什么导致内存转储? 2) 有更好的方法吗


因为我找不到可以执行此操作的工作代码,所以我想我会离开这篇文章,看看是否有更好的方法,并希望它能帮助其他人。

您的代码受到未定义行为的影响。从
stru split
返回之前,您正在呼叫
free(bp)
。但是,
array
的元素指向您在
main
中使用的已释放内存

因为当代码受到未定义行为的约束时,任何事情都可能发生,所以试图寻找其行为的原因是没有意义的

解决此问题的一种方法:

  • 取下衬里

    free(bp);
    
    str\u split

  • main
    中释放内存。第一个标记指向相同的内存位置

    if ( array[0] != NULL )
    {
       free(array[0]);
    }
    

  • 谢谢,这就是我害怕的。我怎么修理它?
    *** Error in `./test': double free or corruption (out): 0x08200018 ***
        ======= Backtrace: =========
    /lib/libc.so.6[0x41681f2d]
    /lib/libc.so.6[0x4168cad9]
    /lib/libc.so.6[0x4168d710]
    ./test[0x8048558]
    ./test[0x80485bf]
    /lib/libc.so.6(__libc_start_main+0xe7)[0x41631687]
    ./test[0x80483f1]
    ======= Memory map: ========
    08048000-08049000 r-xp 00000000 b3:0a 48         /home/root/test
    08049000-0804a000 rw-p 00000000 b3:0a 48         /home/root/test
    08200000-08221000 rw-p 00000000 00:00 0          [heap]
    415e9000-41609000 r-xp 00000000 b3:08 14919      /lib/ld-2.19.so
    41609000-4160a000 r--p 0001f000 b3:08 14919      /lib/ld-2.19.so
    4160a000-4160b000 rw-p 00020000 b3:08 14919      /lib/ld-2.19.so
    41618000-41787000 r-xp 00000000 b3:08 15236      /lib/libc-2.19.so
    41787000-41788000 ---p 0016f000 b3:08 15236      /lib/libc-2.19.so
    41788000-4178a000 r--p 0016f000 b3:08 15236      /lib/libc-2.19.so
    4178a000-4178b000 rw-p 00171000 b3:08 15236      /lib/libc-2.19.so
    4178b000-4178e000 rw-p 00000000 00:00 0
    41a3f000-41a52000 r-xp 00000000 b3:08 14923      /lib/libgcc_s.so.1
    41a52000-41a53000 rw-p 00013000 b3:08 14923      /lib/libgcc_s.so.1
    b77b4000-b77b5000 rw-p 00000000 00:00 0
    b77b8000-b77ba000 rw-p 00000000 00:00 0
    b77ba000-b77bb000 r-xp 00000000 00:00 0          [vdso]
    bf7e3000-bf804000 rw-p 00000000 00:00 0          [stack]
    Aborted
    
        #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int str_split(char **array, char *buf, char *sep, int max){
            char *token;
            int i = 0;
            int size = 0;
            char *bp = strdup(buf);
            while (  ((token = strsep(&bp,sep))!= NULL ) ) {
                    if (i < max ) array[i++] = token;
            }
            i = (i > max)? max : i; 
            array[i] = NULL;  // set to null
            size = i;
            free(bp);
    
        return size;
    }
    
    main(){
        char buf[100];
            strcpy(buf,  "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*35");
            char *array[50];
        char sep[] = "*,";
      int number =  str_split(array, buf+1, sep, 5);  // number is number of elements in array
        int i;
            for (i = 0; array[i] != NULL; i++) printf("%s\n",array[i]);
    return 0;
    }
    
    free(bp);
    
    if ( array[0] != NULL )
    {
       free(array[0]);
    }