前段项目中发现一个问题,程序总是在某个dynamic_cast进行动态转换时出异常,查了半天才发现问题原来是出在memset的使用上,虽然问题本身显而易见,但当处于几十万行代码量级中时,就变得不太那么容易定位了。
- char data[10];
- memset(data, 1, sizeof(data)); // right
- memset(data, 0, sizeof(data)); // right
- int data[10];
- memset(data, 0, sizeof(data)); // right
- memset(data, -1, sizeof(data)); // right
- memset(data, 1, sizeof(data)); // wrong, data[x] would be 0x0101 instead of 1
- struct Parameters {
- int x;
- int* p_x;
- };
- Parameters par;
- par.p_x = new int[10];
- memset(&par, 0, sizeof(par));
- class BaseParameters
- {
- public:
- virtual void reset() {}
- };
- class MyParameters : public BaseParameters
- {
- public:
- int data[3];
- int buf[3];
- };
- MyParameters my_pars;
- memset(&my_pars, 0, sizeof(my_pars));
- BaseParameters* pars = &my_pars;
- //......
- MyParameters* my = dynamic_cast<MyParameters*>(pars);
memset函数详细说明
1。void *memset(void *s,int c,size_t n)
总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c。
2。例子
main(){
char *s="Golden Global View";
clrscr();
memset(s,'G',6);//貌似这里有点问题//
printf("%s",s);
getchar();
return 0;
}
【这个问题相当大,程序根本就运行不下去了,你这里的S志向的是一段只读的内存,而你memset又试图修改它,所以运行时要出错,修改办法char *s修改为char s[]】
函数原型
memset(dist , val,size);
char test[64];
memset(test, 0,sizeof(test))、或者memset(test,'A',sizeof(test))没有任何问题,可以完成数组的正确填充。
同比:
int test[64];
memset(test,0,sizeof(test))应该能够将test 数组的每个元素填充为0,经验证,同样可以;
但
memset(test,1,sizeof(test)),理论上能够test数组的每个元素填充为1,事实是,test数组中出现的是:0x01010101(十六进制)。
为什么填充失败了?
反过头来看memset函数说明,memset是采用将val逐字节填充到dist中去。
当数组为char类型时,sizeof(char)==1,没有问题;
数组为int类型时,sizeof(int)==4,memset 会将数组元素的四个字节均填充为val,对应数值1,就是00000001000000010000000100000001,当转化成二进制时,就不可能是1了。
所以,使用memset填充数组时,需要牢记其是逐个字节填充。
发现memset的这个问题是源于对指针数组和数组指针的理解,两者在c++可谓是相当强大,易于混淆,偶尔捡起来回顾一下,甚好!
鉴于网上诸多关于指针数组、数组指针的用法介绍,我就不再献丑赘述,仅贴上例子,简单明了(其实,网上资源稂莠不齐,错误的讲解很多,关键还需要靠自己验证,才能明白个中道理)
int _tmain(int argc, _TCHAR* argv[])
{
//指针数组
int *p[N];
memset(p,NULL,sizeof(p));
for (int i=0;i<N;i++)
{
p[i]=new int ;
*p[i]=i;
}
for (int i=0;i<N;i++)
{
delete p[i];
p[i]=NULL;
}
int array[8][8];
//数组指针
int (*arrayPointer)[N];
arrayPointer=array;
for (int i=0;i<N;i++)
{
memset(arrayPointer,i,sizeof(int)*N);
arrayPointer++;
}
//int p1[100]等价如下:
int *p1=new int [100];
printf("0x%p\n",p1);
for (int i=0;i<100;i++)
{
p1[i]=i;
printf("%-4d \n",p1[i]);
}
delete p1 [];
return 0;
}
所说的数组和int 类型指针等价,是我自己个人的理解,数组会由编译器自动分配内存,int类型的指针可以由我们控制内存的分配。
对指针数组深入透彻明白以后,利用指针数组管理类的设计模式也就云开雾明了;
对数组指针深入透彻明白以后,利用数组指针操纵矩阵便再无违和之感了。
鄙人不才、献丑。
c++,openGL,cg learning on my way