我正在尝试使用split
中的perl
和awk
编写我自己的strtok_r
函数,C
创建数组以及返回数字在数组中的元素,我尝试了一些东西,但我没有得到正确的动态内存分配的概念,请有人纠正我,也请发表评论。
我相信strdup
会照顾内存分配吗?
错误:分段错误(核心转储)
这是我到目前为止所尝试的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int split(char * str, char **fields, const char *sep)
{
char *copy = strdup(str), *tmp, *word;
int count=0;
word = strtok_r(copy, sep, &tmp);
while(word)
{
word=strtok_r(NULL, sep, &tmp);
fields[count] = strdup(word);
count++;
}
return count;
}
int main()
{
char string[80]="a,b,c,d,e,f,g,h,i,j,k,l";
const char *sep = ",";
char **cols; int i;
cols = malloc(strlen(string)+1*sizeof(char *));
printf("%s\n",string);
int n = split(string,cols,sep);
printf("%s\t%d\n",string,n);
for(i=0; i<n; i++)printf("%s\t%s\n",string,cols[i]);
free(cols);
return 0;
}
提前致谢所有志愿者
答案 0 :(得分:1)
你有很多初学者错误:
1)为cols
分配内存,例如。在致电main()
之前split()
:
cols=malloc(sizeof *cols * 256);
根据需要调整数字256,或根据编号计算数字。你在string
中的“,”。
2)你的循环部分是错误的,因为你在检查NULL或存储前一个标记之前再次标记 :
while(word)
{
word=strtok_r(NULL, sep, &tmp);
fields[count] = strdup(word);
count++;
}
将标记化作为循环中的最后一个语句:
while(word)
{
fields[count] = strdup(word);
count++;
word=strtok_r(NULL, sep, &tmp);
}
3)您还应该在copy
之前释放split()
,然后再返回。否则,你的程序会有内存泄漏。请记住strdup
为您分配内存(并且您应该检查它是否也返回NULL),但是您负责free
它。
free(copy);
同样适用于为cols[*]
分配的内存。即在main()
中打印字符串后,执行:
for(i=0;i<n;i++)
free(cols[i]);
虽然,在程序终止之前并不是必须释放内存(因为大多数现代操作系统都会解除分配),但清理自己是一种很好的做法。
4)使用main()
的标准原型,例如:int main(int argc, char*argv[])
或int main(void)
。