none
一个小问题的咨询 RRS feed

  • 问题

  • char *str = NULL;

    str = "fe";这种赋值是在栈上实现的。但是本人现在有种疑惑,如果像这样直接给指针赋值,但是指针又没有确定他指向的空间分配的大小。本人觉得这样应该会有隐患,但是又说不上来到底什么隐患。调试的时候又能通过。希望指导老师能帮忙从底层分析原因。

    顺便问另一个问题,最近总结函数的安全性问题,比如strcpy,用了一段时间改成了strcpy_s,然后改成了strncpy_s.本人觉得这个strncpy,像strncat,strncmp等函数,安全性很好。想以后都用这几个函数了,不知道在性能方面会有什么样的影响,同时应该注意哪些方面来避免它们自身造成的问题。最后一个问题就是我想得到更多这样类似的函数,但上网找了许久也没能搜索到。不知道是否还有其他类似的在中间加个n这样的安全性好的函数。能不能说下它的历史,当然这个问题给个链接,或者提示就行了。初学者,望老师多提点。

    2011年11月8日 3:36

答案

  • 首先 "fe" 是一个引用,类似地址的东西,把这个赋值给 str 是完全没有问题的,就像你在程序中的指针赋值一样。

    至于 "fe" 在哪里,那么是编译器的替你考虑的。

     

    至于 strcpy 是用来进行字符串赋值的,而 C 语言的字符串是以 '\0' 为结束的。而 strcpy 的两个参数只有 源参数有大小,而目标参数没有大小限制,那么该函数要求,赋值的目标参数有至少源参数的缓冲区空间。

    在使用的过程中如果目标参数空间小于源参数大小,那么就会造成缓冲区溢出,破环堆栈或堆。假如目标参数的缓冲区在堆栈上,那么就可以精心设置一个源参数,造成堆栈错误,引起函数返回之后的不正确跳转之类的,最早的莫里斯蠕虫就渊源于此。

    现在的很多门操作都会切换堆栈,所以几乎不存在这个问题。

    但是,这不是这个函数不安全的原因,不安全的原因是,这个函数在使用时又一个要求,那么就是复制是必须保证有足够的缓冲区。这就是为什么提倡契约编程的原因。

    但是,很多人在写程序的时候不注意这个问题,就像 C++ 的 delete 一样。

    所以,给那些人提供了一个安全版的函数 strcpy_s,仅仅添加一个目标缓冲区大小,这样,如果缓冲区溢出,那么产生一个 CRT 断言,就是我们经常看到的那个 C++ 的对话框。

    至于 strncpy 只是是的源参数的长度不是由字符串自己确定,而是由参数确定。他们使用的场合不同,这个函数同样有一个安全的版本。


    我也有自己的签名档哦!
    2011年11月8日 5:10