我们这里谈论是的c/c++ 系列的内存分析。
1关于指针的指针的问题
struct t {
int a;
int b;
int **p;
}*tp;
tp=(tp*)malloc(sizeof(struct t));
这里我们着重谈论int **p;
在第一步的malloc之后,我们会在堆中获得4个字节的空间存储指针。因为指针的指针也是指针。 我们不妨设这里的指针为指针1
--------------------------------------------------------------
| |
1号内存
---------------------------------------------------------------
因为对于int **p,可以对应于一个二维数组,我们假设该二维数组,只有两行,列数可以不用管理,
我在下面继续用malloc()。
tp->p=(int **)malloc(sizeof(int *)*row_length); ///其中,sizeof(int *)就是4个字节。获取的是指针的大小。row_length就是行数为2
通过上面一次malloc,我们的指针1会指向8个字节,这里的8个字节会存储两个指针,不妨设定前4个字节为指针2,后四个字节为指针3.
然后我们在进行一次malloc()。代码如下:int *q=(int *)malloc(sizeof(int)*length);//这里就相当于q指向了一块内存,我们不妨设定该内存为1号内存。
对于tp->p[0]=q,这样指针2指向了q所指向的内存,即1号内存。当我们给q这块内存重新赋值后,将tp->p[1]=q,同样的道理指针3指向了q所指代的内存区域。
下面转载一位高
char *p1; //定义了一个指针指向了char型数据,也就是说步长为1,p1+1,移动一个存储单元
int *p2; //定义了一个指针指向了int型数据,也就是说步长为4,p1+4,移动了四个存储单元
p1 = (char *)malloc(1024 * 100); //分配了100k字节的空间,p1指针是一个指向char型数据的指针
p2 = (int *)malloc(1024 * 100); //分配了100k字节的空间,p2指针是一个指向int型数据的指针
请问 p1 和 p2 有什么区别? //注意这两块内存空间大小是一样的,就看你以什么样的眼光去看它了,如果以一个char的眼光去看他,那么他有100k个char,如果以一个int的眼光去看他,那么他有25k个int。如果这个空间是一个你开辟来接受数据的buff,而你要以某种数据的样式去取他。可以自己定义个一个结构体,
比如以udp数据头为例子
struct udphdr{
unsigned short src;
unsigned short dest;
unsigned short udplenth;
unsigned short checksum;
}
如果你从offset=0开始就是你想要的数据那么struct udphdr *udp=(struct udphdr *)p1;
或者从某一段offset开始才是你想要的数据,struct udphdr *udp=(struct udphdr *)(p1+offset);
之后你就可以取出数据udp->src=xxx 等等。问题关键就看你用什么样的方式去看他。
p1 = (char *)p2;这句话会造成什么后果?是不是会丢失p2里面存储的地址的高8位?
p2 = (int *)p1;这句话又会造成什么后果?
内存图如下: ______________
|______________|
|_____________|
|_____________|
|_____char _____|
|_____char _____|
|_____char ____|->p1+1
|_____char_____|-->p1
______________
|______________|
|_____________|-->p2+1
|___int高八位 ___|
|___int次高八位__|
|___int次低八位_|
|___int低八位____|-->p2
p1=(char *)p2,首先这是一个赋值语句,你把p2的地址赋值给了p1,如果这样做你没有保存p1的地址,malloc数据是在堆里分配的,需要free掉的,p1的地址你已经找不到了,等着内存泄露吧。而(char *)p2这个本身没有问题,意思就算让p1以一个char的眼光去看到p2而已;
p2=(int *)p1;就是让p2以一个int的眼光来看待p1。数据本身没有丢,都是100k的数据。
最主要的后果就是内存泄露。无法free掉原来p1所指向的推拉。