小可爱~ 发表于 2016-1-11 21:32

【笔记】今天复习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


其实这个问题很简单!解决问题的关键是在在乎不在乎这几个字节大小的空间

所以在这题做个笔记提示自己还有上面没有发现问题的友友


申请内存的时候习惯多一点


newerplayer 发表于 2016-1-17 09:39

小可爱~ 发表于 2016-1-17 00:08
其实我觉得那个len 在赋值时没有考虑到'\0'的问题 ! 也知道strlen不包括'\0'
这里就得考虑下 是留给 主 ...

看来你误会了我的意思。

我只是说,你在函数中申请空间时,没考虑到字符串结尾的\0的占位问题,导致少申请了一个char字节的空间。

还有memset函数,经常被用来对新申请的字符串赋初值(一般都约定俗成一长串\0不是吗?当然用0也行,不过可能有时会增加额外的工作),这样做的好处是防止当对字符串操作时,读到内存中原来在这段内存空间已经存在的各种乱七八糟的信息。

按照模块化程序设计的思想,写函数写模块的人需要把函数封装好,把上面那些细节处理好。而写主函数的人只在乎结果,根本不在乎函数内部的实现过程,因为那不是他们操心的事。所以,我认为你的函数存在瑕疵。

以上只是就事论事,言语上有冒犯之处,请多多担待。^_^

小可爱~ 发表于 2016-1-17 00:08

本帖最后由 小可爱~ 于 2016-1-17 00:10 编辑

newerplayer 发表于 2016-1-15 23:16
其实不是malloc的问题,tmp申请字符串内存时,结尾\0该放哪里?
还有操作字符串时,记得用上memset函数, ...
其实我觉得那个len 在赋值时没有考虑到'\0'的问题 ! 也知道strlen不包括'\0'
这里就得考虑下 是留给 主函数开发的人员做这个处理还是 给模块开发的人员去处理了
不过这么一说我倒觉得留给写主函数的去做 写模块的也去做这个处理
毕竟不影响

你同学提的memset我不知道他使用在哪个方面

不过大多数情况下 都是用来初始化一段内存为 0, 如果用在这种情况的话我想说没必要, 因为这段内存即将被赋予初值

还有一种情况是用于初始化 为 '\0'

另外的情况就是有特殊要求了

深海wan° 发表于 2016-1-11 21:37

{:17_1062:}不知道啊,随便看看

Li1y 发表于 2016-1-11 22:23

看看是什么

520_ai_in@sina. 发表于 2016-1-11 22:44

看不懂阴雨

292219828 发表于 2016-1-11 22:58

我就看看

dapuren9129 发表于 2016-1-11 23:10

看看,学习一下

liuman02 发表于 2016-1-12 00:06

看看,学习一下

cinemayy 发表于 2016-1-12 00:13

来看看有啥问题

伴隨你左右 发表于 2016-1-12 14:25

呵呵呵呵呵呵呵呵

latu327 发表于 2016-1-12 14:27

页: [1] 2
查看完整版本: 【笔记】今天复习C语言编写一段字符串反转的代码发现一个问题