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;

历史博文

标签:
七月 2, 2008 at 8:20 上午 by yippee 1,007 次
Category: Info
Tags: