May 8, 2009
在本篇日志讨论的是一组内存分配的函数: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!
May 8, 2009
在本篇和下一篇日志中,将对两组函数进行讨论。一组是字符串拷贝的,另一组是内存分配的。本篇将要讨论的是字符串分配的一组函数: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!
May 8, 2009
题目:
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 成功 目的串的指针
* 失败 [...]
May 8, 2009
为自已的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 [...]