崩溃中, free报错

lzp729 2010-12-01 04:19:52

//定义
int strsplt(const char* const src, char** const pArr, char cDelim)
{
char * pcStart = *pArr;
int count = 0;
for (int i = 0; i < strlen(src); i++)
if ( src[i] != cDelim ) // found start
{
for (int j = i+1; j <= strlen(src); j++)
if (src[j] == cDelim || src[j] == '\0') // found end, copy
{
strncpy(pcStart,&src[i],j-i);
pcStart[j] = '\0';
count++;
pcStart += j-i+1;
i = j;
break;
}
}
return count;
}
//调用
const char * src = "test1|test2|test3";
char * arr = (char*)malloc(strlen(src)+1);
char * b = arr;
memset(arr,0,strlen(src)+1);
int a = strsplt(src, &arr,'|');
printf("%d\n",a);
printf("%s\n",arr);
printf("%s\n",arr+=strlen(arr)+1);
printf("%s\n",arr+=strlen(arr)+1);
printf("%s\n",arr+=strlen(arr)+1);
free(b);


输出正常, free挂在系统库里... vs2010, gcc都是, 崩溃中, 求教...
...全文
490 41 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
chen870201 2010-12-02
  • 打赏
  • 举报
回复
换个思路呢
lzp729 2010-12-02
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 bluewanderer 的回复:]

除非循环过程中src中间会突然冒出0来,否则这样该和直接判断src[i]一样0_0... 还是说你直接在src里切了?
[/Quote]
这就是奇怪的位置, 判断长度就是没问题.... 直接src[i]就会出怪错....
ps: 丫的, 现在还不睡觉...
bluewanderer 2010-12-02
  • 打赏
  • 举报
回复
除非循环过程中src中间会突然冒出0来,否则这样该和直接判断src[i]一样0_0... 还是说你直接在src里切了?
lzp729 2010-12-02
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 bluewanderer 的回复:]

你再怎么折腾字符串也是0结尾的啊|||

就算真不行,每次strlen还不慢死。那就得想别的办法了。
[/Quote]

改成这样呗, 呵呵
int len = strlen(src);
for (int i = 0; i < len; i++)
bluewanderer 2010-12-01
  • 打赏
  • 举报
回复
你再怎么折腾字符串也是0结尾的啊|||

就算真不行,每次strlen还不慢死。那就得想别的办法了。
shadowxmdj 2010-12-01
  • 打赏
  • 举报
回复
不错,正要学这方面的东西,学习下
screwzm 2010-12-01
  • 打赏
  • 举报
回复
b又不是malloc的,你怎么能直接free啊?
lzp729 2010-12-01
  • 打赏
  • 举报
回复
呵呵 上面这个在我自己这边还是有些问题, i循环还是得改用长度判断...

我用这个split一个路径, 比如A\\B\\C\\D

然后对每一个路径递归调用处理函数process(path)
process(B\\C\\D)
process(C\\D)
process(D)
在process里面malloc内存, split的路径, 这样就出问题了, 堆连续分配回造成src[i]的判断错误...
所以还是改成长度比较可靠, 结贴了
lzp729 2010-12-01
  • 打赏
  • 举报
回复
不是最后的打印崩溃, 是j还是错了, j循环的判断也是错了, 我最后贴的那种做法, 没法判断源字符串的结束...

int strsplt(const char* const src, char** const pArr, char cDelim)
{
char * pcStart = *pArr;
int count = 0;
for (int i = 0; src[i]; i++)
if ( src[i] != cDelim ) // found start
{
int j = i+1;
while (true){
if (src[j] == cDelim || src[j] == '\0') // found end, copy
{
memcpy(pcStart,&src[i],j-i);
pcStart[j-i] = '\0';
count++;
pcStart += j-i+1;
i = j;
break;
}
j++;
}
}
return count;
}

这次改的这个可能差不多了... 起码跟我预想的一致, 最多只需要比源串长一个的空间就足够
char * arr = (char*)malloc(strlen(src)+1);
bluewanderer 2010-12-01
  • 打赏
  • 举报
回复
换句话说根本不是申请内存的问题,你这个结果的长度必然小于等于源的长度。
bluewanderer 2010-12-01
  • 打赏
  • 举报
回复
肯定是你最后一个printf崩溃了,总共就三个你打印四个,自然不安全。
lzp729 2010-12-01
  • 打赏
  • 举报
回复
郁闷 还是错的
lzp729 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 bluewanderer 的回复:]

他那个单纯是把delimiter改成0,绝对不止算不对count那么点问题。之所以free崩溃,是我注释!!!???那行你的0写得地方有点离谱。
[/Quote]
确实错了离谱..... 妈的, 真惭愧, 多谢, 已经改好了, 效率问题也注意了下

int strsplt(const char* const src, char** const pArr, char cDelim)
{
char * pcStart = *pArr;
int count = 0;
for (int i = 0; src[i]; i++)
if ( src[i] != cDelim ) // found start
{
for (int j = i+1; src[j]; j++)
if (src[j] == cDelim || src[j] == '\0') // found end, copy
{
strncpy(pcStart,&src[i],j-i);
pcStart[j-i+1] = '\0';
count++;
pcStart += j-i+1;
i = j;
break;
}
}
return count;
}

现在还有个问题
调用时的内存分配到底要多少个?

const char * src = "||test1||||test2|test3|";
char * arr = (char*)malloc(strlen(src)+1); // 这个free会出错
char * arr = (char*)malloc(strlen(src)+2); // 这个free没问题

bluewanderer 2010-12-01
  • 打赏
  • 举报
回复
他那个单纯是把delimiter改成0,绝对不止算不对count那么点问题。之所以free崩溃,是我注释!!!???那行你的0写得地方有点离谱。
lzp729 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 cranium 的回复:]

引用 23 楼 lzp729 的回复:

还有有点问题, count不好处理


这个需要你自己明确函数的职责,然后稍微修改下就可以了。
[/Quote]

想起来了, 我以前写的时候就是想数对这个count才想我顶贴里那样做的... 隔久了, 当时一些想法忘记了...
lzp729 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 bluewanderer 的回复:]

你错的就是那个j,他写的那个逻辑和你的根本不一样,除非你希望"||"这样算是三个字符串。
[/Quote]

恩 是的, 我原先写的时候也是在j上搞了半天, 我再看看
cranium 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 lzp729 的回复:]

还有有点问题, count不好处理
[/Quote]

这个需要你自己明确函数的职责,然后稍微修改下就可以了。
bluewanderer 2010-12-01
  • 打赏
  • 举报
回复
你错的就是那个j,他写的那个逻辑和你的根本不一样,除非你希望"||"这样算是三个字符串。
lzp729 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 cranium 的回复:]

你的strsplt函数大有问题,这里随便修改了个。

C/C++ code

//定义
int strsplt(const char* const src, char** const pArr, char cDelim)
{
char * pcStart = *pArr;
int count = 0;
for (int i = 0; i < strlen(src);……
[/Quote]

还有有点问题, count不好处理
cranium 2010-12-01
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 lzp729 的回复:]

LS的做法很好, 我还是想知道原来那样做事错在哪里
帖子挂几天, 找不出问题就结贴了
[/Quote]

原来的代码我还是建议你不要再想了。

我上面的代码也只大概写了下,比如最后的NULL就没有加,依赖main里的memset初始化缓冲。

最好,再建议你想想你的函数的职责,要不然就很有可能写出原先的那些代码,太饶了,还容易出错。
加载更多回复(21)

70,023

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧