c在c++中出现的奇怪问题,请高手帮忙解答

alongfly 2003-09-12 01:16:55
我编写的c程序,在vc++中编译,出现了一个奇怪的问题。我的原程序如下,问题在程序的注释中标明:

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

char *Trim(char *str)
{
char *str1;

int i = 0;
int flag=0;


if (str == NULL)
{
return NULL;
}

str1 = (char*)malloc(strlen(str)+1);

while(*str != '\0')
{

if (*str == ' ')
{

}
else
{
str1[i] = *str;
i++;
flag=1;
}
str++;
}

if (flag==0)
{
printf("The string iscomposed of blanks!\n");
return NULL;
}


str1[i] = '\0';

str=&str1[0]; //?这里会泄露内存吗????

str1=NULL; //?如果不用这个语句,free(str1)后就会运行得不到正确结果
free(str1);

return str;
}


void main()
{
char *str;
str=" dd dd dd ";
printf("The original string is: %s\n",str);
printf("After removing the blank string,It is: %s\n",Trim(str));

}
...全文
34 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
alongfly 2003-09-12
  • 打赏
  • 举报
回复
明白了。谢谢。
发份了。
TianGuangZao 2003-09-12
  • 打赏
  • 举报
回复
To alongfly(fang)
用了 str1=NULL; 后。
str1 不指向任何对象, str 仍指向原来的堆,互不相干了。
所以 free(str1); 这个动作不影响 str.
alongfly 2003-09-12
  • 打赏
  • 举报
回复
我觉得天光早说的有道理。还有个疑问,为什么要str1=NULL; free(str1); 它就没有释放掉str呢??
TianGuangZao 2003-09-12
  • 打赏
  • 举报
回复
To jence(jence):
返回 str1 不行, str1 是局部指针,出了作用域就没了,怎么能返回它呢?
返回 str 没错。
alongfly 2003-09-12
  • 打赏
  • 举报
回复
有个规则不是说不能返回子程序里的变量吗?
TianGuangZao 2003-09-12
  • 打赏
  • 举报
回复
str 指向栈。
str1 指向用 malloc 分配的内存,所以指向堆,最后肯定要用 free 释放。
个人认为楼主的程序存在内存泄漏。

{
....
str=&str1[0]; //?这里会泄露内存吗????

str1=NULL; //?如果不用这个语句,free(str1)后就会运行得不到正确结果
free(str1);

return str;
}
....
str 本来是指向栈的,使用 str=&str1[0]; 后,它指向了堆,也就是说 str 和 str1 指向了同一块内存,然后你把它返回给调用函数,这样的话,你把 free 内存的任务交给了 main 函数,个人感觉这样的设计很不好呀!

至于 str1=NULL; free(str1);
是先把 str1 设置为空指针(本来它指向堆),然后释放空指针,虽然没错,但什么也没做,无多大意义。
但如果把 str1=NUll 去掉,那就出错了, free(str1) 就把堆上的内容给释放了;而 str 和 str1 指向同一片内存,返回后结果肯定不正确了。

修改两处:
去掉 free(str1);
在 main 里最后添上: free(str);
jence 2003-09-12
  • 打赏
  • 举报
回复



str=&str1[0]; //?这里会泄露内存吗????
str1=NULL; //?如果不用这个语句,free(str1)后就会运行得不到正确结果
free(str1); //如果没有上一句,你的str1也就是str的内存就会被释放,把这句去掉!!
return str;
}
你不是把str的内容复制到str1上吗?应该返回str1.怎么返回str?应该是程序写错了!str1=NULL;是多余的!
alongfly 2003-09-12
  • 打赏
  • 举报
回复
但是我返回的是str啊
Jinhao 2003-09-12
  • 打赏
  • 举报
回复
重新改写
void Trim(char *str,char *dst)
{
char *str1;

int i = 0;
int flag=0;


if (str == NULL)
{
return NULL;
}

str1 = (char*)malloc(strlen(str)+1);

while(*str != '\0')
{

if (*str == ' ')
{

}
else
{
str1[i] = *str;
i++;
flag=1;
}
str++;
}

if (flag==0)
{
printf("The string iscomposed of blanks!\n");
return NULL;
}


str1[i] = '\0';

strcpy(str1,dst);
}

使用时就这样
void main()
{
char *str=" dd dd dd ";
char *dst;
dst=(char*)malloc(strlen(str)+1);
printf("The original string is: %s\n",str);
printf("After removing the blank string,It is: %s\n",Trim(str,dst));
free(dst);
}
HaiFen 2003-09-12
  • 打赏
  • 举报
回复
最好不要这么做,最好是由上层调用传入缓冲区地址,即由上层调用函数负责分配缓冲区的工作
char * Trim(const char*sou, char* dst)
{
//...
//strcpy(sou, dst);
return dst;
}

void main()
{
char buf[10];
printf("%s", Trim("Hello world", buf));
char * ptrs = "Hell ooo";
char * ptrd = (char*)malloc(strlen(ptrs)+1);
printf("%s", Trim(ptrs, ptrd));
free(ptrd);
}
HaiFen 2003-09-12
  • 打赏
  • 举报
回复
free(strl)没有错,错在free(strl)后,将strl的值返回,然后被printf使用,也就是访问
一段已经被释放的内存,出点小毛病很正常。报告的错误是不是0xc0000005,非法内存访问?
alongfly 2003-09-12
  • 打赏
  • 举报
回复
str1是用malloc分配的,能不free吗?
如果要free,没有前面的str1=NULL,返回的str就是错误的值,而用了它就不会出错。
str以前指向" dd dd dd ",现在str=&str1[0],没有泄露内存吗?
str1移到了字符串的结尾符,如果str = str1,返回的str就是NULL。
请各位高手继续解答。
Jinhao 2003-09-12
  • 打赏
  • 举报
回复
to l1ul1u(apollo) :我说错了


str=&str1[0]; //?这里会泄露内存吗????
导致内存泄露的关键不是在这里
str1=NULL; //?如果不用这个语句,free(str1)后就会运行得不到正确结果
free(str1); //如果没有上一句,你的str1也就是str的内存就会被释放,把这句去掉!!
return str;
}
Jinhao 2003-09-12
  • 打赏
  • 举报
回复
看错了
str=&str1[0]; //?这里会泄露内存吗????不会,导致内存泄露的不是在这里

str1=NULL; //?如果不用这个语句,free(str1)后就会运行得不到正确结果
free(str1); //错在这里,你是在释放一个空指针!!

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

char *Trim(char *str)
{
char *str1;

int i = 0;
int flag=0;

if (str == NULL)
{
return NULL;
}

str1 = (char*)malloc(strlen(str)+1);

while(*str != '\0')
{

if (*str == ' ')
{

}
else
{
str1[i] = *str;
i++;
flag=1;
}
str++;
}

if (flag==0)
{
printf("The string iscomposed of blanks!\n");
return NULL;
}


str1[i] = '\0';

str=&str1[0]; //?这里会泄露内存吗????

str1=NULL; //?如果不用这个语句,free(str1)后就会运行得不到正确结果
free(str1); //如果没有上一句,你的str1也就是str的内存就会被释放,把这句去掉
return str;
}


void main()
{
char *str;
str=" dd dd dd ";
printf("The original string is: %s\n",str);
printf("After removing the blank string,It is: %s\n",Trim(str));

}
jp311 2003-09-12
  • 打赏
  • 举报
回复
str=&str1[0]; //?这里会泄露内存吗????
不必如此写,str = str1就OK了

str1=NULL; //?如果不用这个语句,free(str1)后就会运行得不到正确结果
free(str1);
以上两句,等于释放一个空指针等于什么都没干


没有必要释放str1,因为str1所指之物还要继续被使用

应该再main函数中负责释放
l1ul1u 2003-09-12
  • 打赏
  • 举报
回复
Jinhao(辣子鸡丁)
说的对
Jinhao 2003-09-12
  • 打赏
  • 举报
回复
str=&str1[0]; //?这里会泄露内存吗????
不会,str1是在栈里的
str1=NULL; //?如果不用这个语句,free(str1)后就会运行得不到正确结果
free(str1); //错在这里,不能free,str1不是在堆里,也就是说str1不是由malloc分配的内存

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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