Zhang Jiuan’ Notes

重温malloc,calloc和_alloc几个函数

在本篇日志讨论的是一组内存分配的函数:malloc,calloc和_alloc。下面分对此三个函数分别介绍。
malloc
原型:void * malloc(size_t size);
该函数将在堆上分配一个size byte大小的内存。它分配的单原完全按字节大小计算,因此如此分配N个单原的student_t,那么要这样实现:(stdent_t *)malloc(N * sizeof (student_t));
calloc
原型:void* calloc(size_t size, int count);
该函数解决了上面的函数的不足,它将分配count个size大小的单原,因此在便用此函数的时候就会很方便,比如对上面的例子就可以:(student_t *)calloc(sizeof(t_student), N)就可以了。这样使用就会很清晰的知道分配的内存是一种什么样的逻辑方式。
_alloc
原型:void *_alloc(size_t size);
本函数与上述的两个函数不同,因为它是在栈上分配了size大小的内存,因此使用此函数分配的内存不用再担心内存释放的情况了。但是使用此函数需要注意的是:在函数内部使用此函数分配的内存随着函数的组结不复存在,因此不能将此函数分配的内存供函数外部使用。
好了,今天就到这儿了。
 
thx
张久安
If you enjoyed this post, make sure you subscribe to my RSS feed!

strcpy,strncpy,strlcpy的比较和讨论

    在本篇和下一篇日志中,将对两组函数进行讨论。一组是字符串拷贝的,另一组是内存分配的。本篇将要讨论的是字符串分配的一组函数:strcpy,strncpy,strlcpy
strcpy
    原型:char * strcpy(char *dest, const char *src);
    早期,对于标准C便形成了一组标准库,其中就包括字符串操作的。如:strcmp, strcat, strcpy等。strcpy的功能是将一个字符串的内容原样拷贝到另外一个缓存中。但它存在不安全情况,1 如果接收的缓存太小,便会引起写内存越界的情况;2 这个函数也没有对源串进行一定的判断,也就是不能保证源串的长度和结束标志。于是便有后来的strncpy和strlcpy的产生。
strncpy
    函数原型:char * strncpy(char * dest, const char *src, size_t size);
    此函数似乎有些鬼异,因为接收的size为源串的缓冲区的长度。也就是说源串中的字符最多size个字符可以拷贝到目的串中,它并没有真正解决缓冲区溢出的危险,因为此函数并没有对目的缓冲区做任何的判断。但是它的strcpy相比,已经有了很大的进步,因此它也成了标准C度的一部分。
strlcpy
    原型:char * strlcpy(char *dest, const char *src, size_t dest_buf_size);
                 int strlcpy(char *dest, const char *src, size_t dest_buf_size);
    strlcpy从根本上解决了缓冲区溢出的危险,因为dest_buf_size为目的串的缓冲区的大小,因此此函数最多往目的串中存放dest_buf_size个字符。这样不管源串的大字的缓冲区的大小,都不会造成目的缓冲的溢出情况。但是奇怪的是strlcpy函数却没有成为标准C库的一个组成成员,直到现在。由此也造成了strlcpy的多种接口形式,比如上面描述的两个函数原型。
 
thx
张久安
If you enjoyed this post, make sure you subscribe to my RSS feed!

解答昨天的题目

题目:
void strcpy(char *p1, char *p2)
{
    for (int i = 0; i <= strlen(p1); i++) {
        p1[i] = p2[i];
    }
}
错误:
    1 接口设计不合理
        1.1 不支持字符串链接表达式
        1.2 没有函数正确性判断
        1.3 参数名不清晰,不能够从函数名看出该参数的用途
        1.4 没有对拷贝源串进行const声明
    2 没有对接收参数进行合法性校验
    3 对于标准C不支持for内部声明int i
    4 for内部的strlen会多次计算,效率低
    5 数组有越界情况
    6 源串和目的串混乱,达不到拷贝目的
1 接口:针对上述错误和不足,可以进行如下定义
/**
 * @brief 用于进行字符串拷贝
 * @param dest 目的地址
 * @param src const属性(并不保证src串不可被修改,只是提示程序员不要进行修改),源串
 * @param dest_buf_size目的缓冲区的大小
 * @return 成功 目的串的指针
 *         失败 [...]

为自已的wordpress添加了sidebar

为自已的wordpress添加了sidebar。实际添加方法和过程还是很简单的,虽然走了点弯路。
原来我的页面组成是这样的:
|header                                                             |
|body                       | second     |  third       |
|footer                                                               |
实际上只需要把second调整成sidebar即可。
mv second.php sidebar.php,在编辑文件里就可以找到sidebar.php了,然后再创建一个functions.php文件。
sidebar.php添加出下代码:
 <div id=”sidebar”>
  <ul>
 <?php include (TEMPLATEPATH . ‘/searchform.php’); ?>
 <div>
  <ul>
   <?php wp_register(); ?>
   <li><?php wp_loginout(); ?></li>
   <?php wp_meta(); ?>
  </ul>
 </div>
 <div>
              <h2>分类</h2>
              <ul>
                   <?php wp_list_cats(); ?>
              </ul>
         </div>
   <?php  /* Widgetized sidebar, if you have the plugin installed. */
     if ( !function_exists(’dynamic_sidebar’) || !dynamic_sidebar() ) : ?>
   <?php endif; ?>
  </ul>
 </div>
functions.php文件添加如下代码:
if ( function_exists(’register_sidebar’) ) {
    register_sidebar();
}
好了,现在我的blog已经有sidebar了,可以添加一些小插件了:)
看看效果。坏了,样式变了,都乱了,怎么办?仔细想了想,是因为样式没有按second去配。
于是修改了如下代码,实际只是添了一个属性:
 <?php include (TEMPLATEPATH [...]

,

返回顶部