int str_len =5; str_type *s = (str_type*) malloc( sizeof( str_type ) + str_len -1 ); // free( s );
这个技巧原理很简单,因为_s恰好在结构体尾部,所以可以为其分配一段连续的空间,只要注意指针的使用, 这个就算不上代码上的罪恶。但是这个技巧有个限制,str_type定义的变量必须是被分配在堆上,否则会破 坏堆栈。另外,需要动态增长的成员需要位于结构体的末尾。最后,一个忠告就是,这个是C语言里的技巧, 如果你的结构体包含了C++的东西,这个技巧将不再安全(<Inside the C++ object model>)。
其实select也可以这样做:
事实上,因为select涉及到的fd_set是一个完全满足上述要求的结构体:
winsock2.h : typedef struct fd_set { u_int fd_count; /**//* how many are SET? */ SOCKET fd_array[FD_SETSIZE]; /**//* an array of SOCKETs */ } fd_set;
// read_set, write_set为采用了上文所述技巧的fd_set类型的指针 int r = select( 0, read_set, write_set, 0, &timeout ); // error handling for( int i =0; i < read_set->fd_count; ++ i ) { // 轮询所有socket,这里直接采用read_set->fd_array[i] == now_socket判断,而不是FD_ISSET } for( int i =0; i < write_set->fd_count; ++ i ) { // 轮询所有socket,检查其whether can write,判断方式同上 }