user-0 提问: calloc分配后储存，如何用普通变量读取？

回复:
user: user-0
content: 引用 4 楼 lm_whales 的回复:C更是只有指针可以和动态分配的内存相联系 可否总结为一句话，malloc calloc realloc分配的内存，只能由指针变量读取，不能用普通变量读取。 这句话没错吧？

user: user-0
content: 引用 4 楼 lm_whales 的回复:C更是只有指针可以和动态分配的内存相联系 p1是指针变量，x是普通变量。 int x=0; int *p1=0; p1=calloc(10, sizeof(int)); *p1=1; printf("%p", p1); //p1是用calloc分配出来的指针。 printf("%p", &x); 此时&x必定不等于p1，我不能让x去读取p1位置的值吗？

user: user-1
content: C更是只有指针可以和动态分配的内存相联系

user: user-1
content: 动态分配的内存，本身是没有名字的对象。 所谓普通变量，是有名字的对象，（或者有名字的引用）。 二者联系的方法，通常就是，用指针---有名对象---- 指向该对象  C++可以对指针加以包装，从而隐藏他是个指针的事实。 例如 stl 的 vector ,sting ,以及 share_ptr. PS： C++动态分配的对象，一般使用指针指向它， 而不是引用跟他绑定。  因为C++引用 都是要绑定明确的对象的， 一般是不需要释放内存的，引用的对象释放内存后， 引用本身的存在，就和野指针类似， 变得不可思议了，这也不符合引用的语义。 C++没有空引用，所有引用  都是在定义的时候，绑定到一个对象上的。 所以不适合绑定到动态分配内存的对象上。

user: user-2
content: A[B] *(A+B) *(B+A) B[A] //以上四行等价  "abc"[1] *("abc"+1) *(1+"abc") 1["abc"] //以上四行等价  A[0] *(A) 0[A] //以上三行等价

user: user-3
content: 仅供参考 #include <stdio.h> #include <stdlib.h> int main(void) {     int *p = NULL; 	int *q = NULL; 	int i = 0;     p = (int*)calloc(10, sizeof(int)); 	for(i=0; i<10; i++){ 		p[i] = i+1; 	} 	q = p; 	while(q != p+10){ 		printf("%d ", *q); 		q++; 	}     return 0; }

user: user-1
content: C 定义一个某类型名字，和一个固定地址相关的方法是 用宏定义处理  例如已知 0xA0000000 是直接写屏地址(绘制图形模式).  可以这么定义 #define  directDraw   * (char *)( 0xA0000000 ) 定义一个 char 类型的 地址为0xA0000000 的标识符（变量）  或者  #define Cols   1920  #define Rows 1080 typedef Screen COLOREF [Rows][Cols]; #define directDraw *(Screen*)( 0xA0000000 ) 这就相当于 定义一个地址为  0xA0000000的，名为 directDraw COLOREF 类型的二维数组了 但这不是定义变量的方法，只是一个变通的方法。  这种方法的缺点是，如果这个地址，不是保留地址（固定用途的内存区域）。 那么，可能和系统分配的变量，有冲突 从而造成，程序逻辑紊乱。破坏程序的正常运行。

user: user-1
content: 字符串的确特殊一点，C中，字符串是字符[/color[color=#FF0000]]数组类型 因为C数组和指针关系比较紧密，所以很多时候，用指针 来处理字符串 实际上，C也经常用指针处理数组。 至于说，普通变量不能自己把命名和地址联系起来 因为，C语言，变量的地址是系统分配的。 程序员只负责给变量起个名字，定义一个类型，乃至初始化， 通常，并不能直接把变量名，和固定的内存相联系 动态分配的内存（堆内存），才是程序员可以分配的内存 （但是程序员依然没法给他命名，所以其中的对象，是无名对象） PS： 实际上汇编语言，大多也不会把变量和地址直接关联 但是汇编语言，可以定义数据区，代码区， 这样，数据区内部的变量，相对地址是固定的。 有时候，甚至可以绝对定位数据区，代码区的地址， 从而实现数据区的变量，绝对定位的目的（这样变量名，和地址就一一对应了）

user: user-4
content: 引用 14 楼 qq_16774199 的回复:[quote=引用 12 楼 Happy_BC 的回复:] 个人认为不能使用普通变量读取动态分配， 因为普通变量在编译时已经确定地址， 动态获取的内存空间由操作系统分配，操作系统不会把已经使用的内存再分配吧，  因为不重叠， 所以不可以。（局部变量虽然是动态分配的，但系统同样会让局部变量和calloc分配分间不重叠）  我就是想把已确定的普通变量地址给改了，不过看起来C语言是不能让我为所欲为。[/quote]  因为变量地址编译后是在指令中的。如果可以修改代码段，就可以修改指令中的地址了。 C语言可以通过指针访问所有4GB的空间（我也是新手，刚才试了下访问任意内存，发现能通过编译）所以理论上C语言可以修改代码。  当然也就可以修改编译到指令中的地址了。 比如：  int * p = (int *)10;   然后再使用*p    这种方式就可以访问任意4GB空间了。但是因为代码运行在第3层，没有权限（保护模式：一些重要内存，代码段等没权限的访问不了），windows会弹出异常！ 所以不是C语言的问题，是系统保护的问题。

user: user-5
content: 引用 14 楼 qq_16774199 的回复:[quote=引用 12 楼 Happy_BC 的回复:] 个人认为不能使用普通变量读取动态分配， 因为普通变量在编译时已经确定地址， 动态获取的内存空间由操作系统分配，操作系统不会把已经使用的内存再分配吧，  因为不重叠， 所以不可以。（局部变量虽然是动态分配的，但系统同样会让局部变量和calloc分配分间不重叠）  我就是想把已确定的普通变量地址给改了，不过看起来C语言是不能让我为所欲为。[/quote]  你是想int a [10]，然后calloc一个空间，让a变量代表这个空间吗？...就算能编译过，a变量可能还是只有10个元素，万一calloc的长度不是10个元素。。。

user: user-5
content: 引用 13 楼 qq_16774199 的回复:[quote=引用 11 楼 u012947309 的回复:] [quote=引用 楼主 qq_16774199 的回复:] …… 变量过了周期自己就release了，calloc得自己release。不然一直在内存里，系统不管的。  变量过了周期release，calloc过程结束也应该release吧？比如我最开始发的代码虽没有free，但也会自动free吧？[/quote]  这个周期可能比较大。。。程序大了或者内容多了就不好查了。慢慢就习惯了用完就release了。

user: user-0
content: 引用 12 楼 Happy_BC 的回复:个人认为不能使用普通变量读取动态分配， 因为普通变量在编译时已经确定地址， 动态获取的内存空间由操作系统分配，操作系统不会把已经使用的内存再分配吧，  因为不重叠， 所以不可以。（局部变量虽然是动态分配的，但系统同样会让局部变量和calloc分配分间不重叠）  我就是想把已确定的普通变量地址给改了，不过看起来C语言是不能让我为所欲为。

user: user-0
content: 引用 11 楼 u012947309 的回复:[quote=引用 楼主 qq_16774199 的回复:] …… 变量过了周期自己就release了，calloc得自己release。不然一直在内存里，系统不管的。  变量过了周期release，calloc过程结束也应该release吧？比如我最开始发的代码虽没有free，但也会自动free吧？

user: user-4
content: 个人认为不能使用普通变量读取动态分配， 因为普通变量在编译时已经确定地址， 动态获取的内存空间由操作系统分配，操作系统不会把已经使用的内存再分配吧，  因为不重叠， 所以不可以。（局部变量虽然是动态分配的，但系统同样会让局部变量和calloc分配分间不重叠）

user: user-5
content: 引用 楼主 qq_16774199 的回复:请教，calloc分配内存后，把数字用（*指针）储存到内存里，然后用（*指针）读取这个数字。可是如何用普通变量读取这个内存位置的内容？难道为了读取calloc分配的内存里储存的第1、2、3组数字，只能用*p1 *(p1+1) *(p1+2)。   #include <stdio.h> #include <stdlib.h> int main(void) { 	int *p1=0; 	int x=0; 	p1=calloc(10, sizeof(int)); 	*p1=1; 	*(p1+1)=2; 	return 0; }    是的呀，普通变量，你or系统知道他指向某个内存空间，这个变量就是这一段内存空间的名字。 int a =10; 系统在内存中开辟了一个4个字节32位长度的空间。命名为a。内存空间存了10这个数。  calloc malloc之类的，在系统内部动态开辟一个空间。但是没有给变量名。变量开辟是编译时候就开辟好了，不是运行时候再开辟。 int *p1=calloc(10, sizeof(int)); 这是相当于开辟了两串内存空间，一串空间是calloc 10 sizeof int； 另一个空间名叫p1，是int *类型，这串内存存的是calloc空间的首地址。 系统根本不知道calloc开辟的那串空间在哪，只知道你让p1存了那串空间的地址。 而且系统不知道calloc那串空间所代表的数据的类型和长度。 系统不知道访问这串空间要隔着一个int为步伐还是以short为步伐。而且不知道这传连续的空间到哪停止。 所以需要p+1 p+2 这种方式读取。哪怕p+11系统也会去读，至于这么位置有没有数据，是什么，就不知道了。 系统只知道你让他读p+1是p这个位置往后1个单位（int）的位置。 所以用calloc的一定记得长度。 另外，因为calloc开辟的空间不像开辟一个变量空间。 变量过了周期自己就release了，calloc得自己release。不然一直在内存里，系统不管的。

user: user-6
content: 引用 9 楼 qq_16774199 的回复:整形、浮点、布尔、字符类型写一章，不易察觉字符串对C来说是整型。 字符串?

user: user-0
content: 引用 7 楼 lm_whales 的回复:[quote=引用 6 楼 qq_16774199 的回复:] [quote=引用 4 楼 lm_whales 的回复:] C更是只有指针可以和动态分配的内存相联系 可否总结为一句话，malloc calloc realloc分配的内存，只能由指针变量读取，不能用普通变量读取。 这句话没错吧？[/quote] 不叫读取，叫记录。指针可以表示地址。  用指针记录一下地址，下次就可以找到他了 可以读，也可以写。  有名字的对象，可以用名字加以区分，也可以用地址加以区分。  没有名字的对象，只好用地址加以区分， 因此，用指针储存，它的地址，就可以随时使用它了。  指针本来就属于普通变量。 不过不是 整型，浮点型这一类表示数学量的类型。 ----bool，也是一种数学类型，c最初没有独立的bool,C++ 有，C99标准也有了-----  也不是记录 自然语言的字符，字符串类型----C中，字符属于整型------ 而是表示计算机本身 的内存地址的类型。  [/quote]  许多C语言书指针单独写一章，初学者误以为指针是另外一种东西。 整形、浮点、布尔、字符类型写一章，不易察觉字符串对C来说是整型。

user: user-1
content: 其实如果，编程语言没有指针类型，也是一样可以操作内存中的数据。 只是没有有指针的语言方便而已。

user: user-1
content: 引用 6 楼 qq_16774199 的回复:[quote=引用 4 楼 lm_whales 的回复:] C更是只有指针可以和动态分配的内存相联系 可否总结为一句话，malloc calloc realloc分配的内存，只能由指针变量读取，不能用普通变量读取。 这句话没错吧？[/quote] 不叫读取，叫记录。指针可以表示地址。  用指针记录一下地址，下次就可以找到他了 可以读，也可以写。  有名字的对象，可以用名字加以区分，也可以用地址加以区分。  没有名字的对象，只好用地址加以区分， 因此，用指针储存，它的地址，就可以随时使用它了。  指针本来就属于普通变量。 不过不是 整型，浮点型这一类表示数学量的类型。 ----bool，也是一种数学类型，c最初没有独立的bool,C++ 有，C99标准也有了-----  也不是记录 自然语言的字符，字符串类型----C中，字符属于整型------ 而是表示计算机本身 的内存地址的类型。