20071013 变参 指针数组
http://www.yippeesoft.com
c语言中的指针数组怎样释放?
如
char *pt[10],
令
pt[0]="abc";
pt[3]="word sfe";
看下例:
char *p,int *q;
p="5";/*是可以的—-字符串常量的空间由编译器指定到数据段中了*/
q=5;/*是不可以的—-只分配了指针的空间,但并有申请指针指向的空间!*/
楼主的问题中,是不需要手动释放指针指向的内容,它会随程序退出而自动释放。
只有成功执行了malloc或其他内存分配函数,才需要free
问题出在这句上
str[i]=(char *)new char[strlen(string)];
申请的空间少了一个, 需要改成
str[i]=(char *)new char[strlen(string)+1];
因为strlen()只是计算字符串的有效长度的. 而实际的字符串存储空间需要是有效长度再加上一个串结束符\’\\0\’, 所以申请的空间是strlen(string)+1
char**buff = new char*[number];后 delete []buff;前各加一个printf("%p", buff);
——————————————————–
直接delete []buff;就可以了
C中的可变参数的实现主要是利用了C函数在参数入栈的时候是从右往左的特性,具体实现的时候可以借助ANSI定义的stdarg.h里面的1个类型定义和4个宏定义:
typedef char * va_list; /* ALPHA 平台下不是这个定义 */
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) – 1) & ~(sizeof(int) – 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) – _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
下面逐一说明4个宏定义:
_INTSIZEOF
这个宏计算出了参数n在int对齐方式下,所占内存的字节数。这个主要是内存对齐的要求。如尽管n是一个char型的变量,在一般的IA32平台上,它还是会占用4个字节,也就是压栈的时候还是4个字节表示了这样一个char,这时,如果直接使用sizeof(char)得出的自然就是一个错误的偏移。同时,使用sizeof(int)而不是4,也考虑到了平台的通用性,int也可能为2,8,甚至是16
va_start
这个宏得到的是第一个可变参数在栈中的值,注意:不是第一个参数,而是第一个可变参数。v是第一个固定参数,取得它的地址后,通过加上一个自己的大小,就可以得到第一个可变参数(前提是压栈的时候,栈往低地址方向变化)。非常简单!
va_arg
这个宏得到当前可变参数的值,并且使得一个临时的va_list变量指向下一个可变参数的起始地址。注意,这里有一个似乎挺愚蠢的写法:x+y-y,何必要加了又减去呢?仔细观察就会发现,主要是为了在一句里面完成ap下移到下一个可变参数的操作。当然,可以写成&leftsign;*(t*)ap;ap += _INTSIZEOF(t);&rightsign;
va_end
重置了va_list变量。对程序的执行没有任何影响。
ascii中用宏:va_list, va_arg, va_start, va_end 四个宏来实现参数变化的函数,估计其原理是:
调用函数时,传入的参数在栈中按(高地址——〉低地址,最后一个参数——〉第一个参数)排列,知道第一个参数的地址,
那么只需要顺序地知道各个参数的类型就可以取出各个参数的值。
例如:
#include <stdarg.h>
void f(int first, int second, …)&leftsign; //必须知道至少一个参数。why?为了知道参数的起始地址吗?
cout << "f(" << first;
va_list vaList; //宏va_list
va_start(vaList, second); //宏va_start要以最后一个参数为自己的参数。why?为了知道变参的起始地址吗?
int i = va_arg(vaList, int); //宏va_arg要以类型(比如int)为自己的参数,“返回值”为该类型的值,此即为实际传入的参数
//注意:依次返回second参数后面的参数,不含second。
while ( i != -1 )&leftsign;
cout << ", " << i;
i = va_arg(vaList, int);
&rightsign;
va_end(vaList); //宏va_end一般负责将指针vaList=0
cout << ")\\n";
&rightsign;
我们在C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为:
int printf( const char* format, …);
它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的(用三个点“…”做参数占位符),实际调用时可以有以下的形式: printf("%d",i);
printf("%s",s);
printf("the number is %d ,string is:%s", i, s);
以上这些东西已为大家所熟悉。但是究竟如何写可变参数的C函数以及这些可变参数的函数编译器是如何实现,这个问题却一直困扰了我好久。本文就这个问题进行一些探讨,希望能对大家有些帮助.
二、写一个简单的可变参数的C函数
先看例子程序。该函数至少有一个整数参数,其后占位符…,表示后面参数的个数不定. 在这个例子里,所有的输入参数必须都是整数,函数的功能只是打印所有参数的值.
函数代码如下:
//示例代码1:可变参数函数的使用
#include "stdio.h"
#include "stdarg.h"
void simple_va_fun(int start, …)
&leftsign;
va_list arg_ptr;
int nArgValue =start;
int nArgCout=0; //可变参数的数目
va_start(arg_ptr,start); //以固定参数的地址为起点确定变参的内存起始地址。
do
&leftsign;
++nArgCout;
printf("the %d th arg: %d\\n",nArgCout,nArgValue); //输出各参数的值
nArgValue = va_arg(arg_ptr,int); //得到下一个可变参数的值
&rightsign; while(nArgValue != -1);
return;
&rightsign;
int main(int argc, char* argv[])
&leftsign;
simple_va_fun(100,-1);
simple_va_fun(100,200,-1);
return 0;
&rightsign;
历史博文
- vivi 1 - 2010
- 20081030 c# socket udp python - 2009
- 20070129 windows gtk install - 2007
- 0306 printer drv Reflector for .NET - 2006
- Fire to UC/OSII 向ucos2开火 - 2005
- TortoiseCVS中文帮助-取出模块 - 2005
- Dietary Guidelines for Americans美国饮食指导3 - 2005
- Dietary Guidelines for Americans美国饮食指导2 - 2005
- 失败的ASP.NET MONO之旅ADO.NET - 2005