函数通过c中的多个分隔符将字符串拆分为数组
编辑:感谢@R Sahu在我的例程中找到了bug。对于感兴趣的读者,以下是更正的代码:函数通过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
#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]);
}