【笔记】今天复习C语言编写一段字符串反转的代码发现一个问题
本帖最后由 奋斗丶小Z 于 2016-1-12 22:55 编辑大家看下这段代码是否存在问题???自己先试着看看不要放入编译器中调试运行先
#define_CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int WorkStr(const char *str1, char **OutStr, int len)
{
int ret = 0;
char *p1 = NULL, *p2 = NULL;
char *tmp = NULL;
char tmp_value;
if (NULL == str1 || 1 >= len)
{
ret = -1;
printf("func WorkStr err: %d \n", ret);
return ret;
}
tmp = (char *)malloc(sizeof(char) * len);
strcpy(tmp, str1);
p1 = tmp;
p2 = p1 + strlen(tmp) - 1;
while (p1 < p2)
{
tmp_value = *p1;
*p1 = *p2;
*p2 = tmp_value;
p1++;
p2--;
}
*OutStr = tmp;
printf("tmp:%p\n", tmp);
return ret;
}
int main()
{
char *str1 = "abcd";
char *str2;
int rv = 0;
int len = strlen(str1);
rv = WorkStr(str1, &str2, len);
if (-1 == rv)
{
return rv;
}
printf("%s\n", str2);
printf("str2:%p\n", str2);
free(str2);
system("pause"); return rv;
}
2.实在没发现就试着赋值到自己的编译器上试试
发现问题了么???
问题提示:在malloc那行出现了一个巨大的bug
其实这个问题很简单!解决问题的关键是在在乎不在乎这几个字节大小的空间
所以在这题做个笔记提示自己还有上面没有发现问题的友友
申请内存的时候习惯多一点
小可爱~ 发表于 2016-1-17 00:08
其实我觉得那个len 在赋值时没有考虑到'\0'的问题 ! 也知道strlen不包括'\0'
这里就得考虑下 是留给 主 ...
看来你误会了我的意思。
我只是说,你在函数中申请空间时,没考虑到字符串结尾的\0的占位问题,导致少申请了一个char字节的空间。
还有memset函数,经常被用来对新申请的字符串赋初值(一般都约定俗成一长串\0不是吗?当然用0也行,不过可能有时会增加额外的工作),这样做的好处是防止当对字符串操作时,读到内存中原来在这段内存空间已经存在的各种乱七八糟的信息。
按照模块化程序设计的思想,写函数写模块的人需要把函数封装好,把上面那些细节处理好。而写主函数的人只在乎结果,根本不在乎函数内部的实现过程,因为那不是他们操心的事。所以,我认为你的函数存在瑕疵。
以上只是就事论事,言语上有冒犯之处,请多多担待。^_^ 本帖最后由 小可爱~ 于 2016-1-17 00:10 编辑
newerplayer 发表于 2016-1-15 23:16
其实不是malloc的问题,tmp申请字符串内存时,结尾\0该放哪里?
还有操作字符串时,记得用上memset函数, ...
其实我觉得那个len 在赋值时没有考虑到'\0'的问题 ! 也知道strlen不包括'\0'
这里就得考虑下 是留给 主函数开发的人员做这个处理还是 给模块开发的人员去处理了
不过这么一说我倒觉得留给写主函数的去做 写模块的也去做这个处理
毕竟不影响
你同学提的memset我不知道他使用在哪个方面
不过大多数情况下 都是用来初始化一段内存为 0, 如果用在这种情况的话我想说没必要, 因为这段内存即将被赋予初值
还有一种情况是用于初始化 为 '\0'
另外的情况就是有特殊要求了 {:17_1062:}不知道啊,随便看看 看看是什么 看不懂阴雨 我就看看 看看,学习一下 看看,学习一下 来看看有啥问题 呵呵呵呵呵呵呵呵
页:
[1]
2