今天写个二叉树程序犯了个很基础的错误,试图通过传递非地址参数来改变参数的值,程序结果直接内存报错,访问的内存不可写,把写得代码问杰哥帮忙,杰哥一看就知道问题哪儿了,杰哥建议单步调试多看看C语言变量的内存地址,于是 自己也将错就错来写了段测试代码,发现不少问题,如下:
所有参数的值如下
tmp1=2293620;
temp1=4;
temp2=16;
temp3=1;
temp4=4;
temp5=24;
temp6=17;
temp7=4072632;
temp8=4072640;
temp9=4072644;
temp10=4072648;
temp11=2293584;
temp12=2293612;
temp0=2293612;
我们可以分析了,我用的调试平台是dev4.9版本,这里tmp1=&aa,temp11=&tt;但是tmp1=2293620,temp11=2293584 两个地址值并不一样,由此可知,如杰哥所说,参数传递时候,系统会拷贝一份参数值来传递,并不是原来的参数直接作为参数传递,所以tmp1!=temp11.继续分析,temp4=4 temp1=4这个就很容易理解了,两个都是指针类型,分配4个字节的大小来存储,但他们的存储地址确有的玩味,如temp11=2293584,temp9=4072644,temp10=4072648;temp9和temp10刚好相差了4个字节,temp11和temp9相差的就大了,也就是说系统为不同函数存储的位置不是按顺序存储的(这个结论待定),temp9 和temp10是存储在栈中,地址值是向上升.我们这里又发现tmp1=&aa和 temp11这两个地址值相差很仅,所以应该是temp11在main函数中系统已经分配内存了,而不是运行到tests函数中分配的,temp0=&bb,bb是我们动态分配的地址,这里temp0=2293612, tmp1 ,temp11,temp0地址是向下降的,这个和局部变量的存储方式不一样,不知道为什么,网上说程序员动态分配的都存储在堆里面,堆里是从高地址到低地址的?不得而知。 程序中发现个意外的收获,temp5!=temp6,照常规理解,应该是相同的,网上求百度,果然有答案,是不同的内存对齐方式所决定的,还没仔细学习,继续研究。
#include "stdio.h"
#include "malloc.h"
#include "stdlib.h"
struct test
{
double i;
char c;
struct test *p;
struct test *q;
};
int tests(struct test * tt)
{
int temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9,temp10,temp11,temp12;
struct test st;
tt=(struct test *)malloc(sizeof(struct test));
tt->i=5;
tt->p=NULL;
tt->q=NULL;
temp1=sizeof(tt->p);
temp2=sizeof(tt->i);
temp3=sizeof(tt->c);
temp4=sizeof(tt);
temp5=sizeof(struct test);
temp6=sizeof(double)+sizeof(char)+sizeof(struct test *)*2;
temp7=&(tt->i);
temp8=&(tt->c);
temp9=&(tt->p);
temp10=&(tt->q);
temp11=&tt;
temp12=&st;
return 0;
}
int main()
{
struct test *aa=NULL;
int tmp1=&aa;
tests(aa);
struct test * bb=NULL;
bb=(struct test *)malloc(sizeof(struct test));
int temp0;
temp0=&bb;
aa->p=bb;
bb->p=bb->q=NULL;
free(aa);
printf("hello world");
system("PAUSE");
return 0;
}
所有参数的值如下
tmp1=2293620;
temp1=4;
temp2=16;
temp3=1;
temp4=4;
temp5=24;
temp6=17;
temp7=4072632;
temp8=4072640;
temp9=4072644;
temp10=4072648;
temp11=2293584;
temp12=2293612;
temp0=2293612;
我们可以分析了,我用的调试平台是dev4.9版本,这里tmp1=&aa,temp11=&tt;但是tmp1=2293620,temp11=2293584 两个地址值并不一样,由此可知,如杰哥所说,参数传递时候,系统会拷贝一份参数值来传递,并不是原来的参数直接作为参数传递,所以tmp1!=temp11.继续分析,temp4=4 temp1=4这个就很容易理解了,两个都是指针类型,分配4个字节的大小来存储,但他们的存储地址确有的玩味,如temp11=2293584,temp9=4072644,temp10=4072648;temp9和temp10刚好相差了4个字节,temp11和temp9相差的就大了,也就是说系统为不同函数存储的位置不是按顺序存储的(这个结论待定),temp9 和temp10是存储在栈中,地址值是向上升.我们这里又发现tmp1=&aa和 temp11这两个地址值相差很仅,所以应该是temp11在main函数中系统已经分配内存了,而不是运行到tests函数中分配的,temp0=&bb,bb是我们动态分配的地址,这里temp0=2293612, tmp1 ,temp11,temp0地址是向下降的,这个和局部变量的存储方式不一样,不知道为什么,网上说程序员动态分配的都存储在堆里面,堆里是从高地址到低地址的?不得而知。 程序中发现个意外的收获,temp5!=temp6,照常规理解,应该是相同的,网上求百度,果然有答案,是不同的内存对齐方式所决定的,还没仔细学习,继续研究。