| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 8588 人关注过本帖
标题:[讨论]char* a = "abc" 和 char a[] = "abc" 之间的区别 ...
只看楼主 加入收藏
静思
Rank: 3Rank: 3
来 自:沈阳
等 级:新手上路
威 望:8
帖 子:630
专家分:0
注 册:2006-2-28
收藏
得分:0 
我觉得把内存分布弄清楚,这些问题就没这么复杂了...
char *a="abc"在常量区或者静态存储区,这个跟编译器有关。而char a[]="abc"在栈存储区中,而不在堆存储区中,堆存储区一般通过申请内存获得,比如大家所熟悉的new操作..

[此贴子已经被作者于2007-9-20 22:42:34编辑过]


英者自知,雄者自胜
2007-09-20 22:32
百年不亮
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:789
专家分:0
注 册:2006-4-14
收藏
得分:0 

楼主确定要看内存分配?好吧我贴出来,已经在这个版贴过三次,可惜找不到了


C语言跟内存分配方式
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多
C语言跟内存申请相关的函数主要有 alloca,calloc,malloc,free,realloc,sbrk等.
其中alloca是向栈申请内存,因此无需释放. malloc分配的内存是位于堆中的,并且没有
初始化内存的内容,因此基本上malloc之后,调用函数memset来初始化这部分的内存空间.
calloc则将初始化这部分的内存,设置为0. 而realloc则对malloc申请的内存进行大小的
调整.申请的内存最终需要通过函数free来释放. 而sbrk则是增加数据段的大小;

malloc/calloc/free基本上都是C函数库实现的,跟OS无关.C函数库内部通过一定的
结构来保存当前有多少可用内存.如果程序malloc的大小超出了库里所留存的空间,那么
将首先调用brk系统调用来增加可用空间,然后再分配空间.free时,释放的内存并不立即
返回给os,而是保留在内部结构中. 可以打个比方: brk类似于批发,一次性的向OS申请大
的内存,而malloc等函数则类似于零售,满足程序运行时的要求.这套机制类似于缓冲.
使用这套机制的原因: 系统调用不能支持任意大小的内存分配(有的系统调用只支持固定大小以及其倍数的内存申请,这样的话,对于小内存的分配会造成浪费; 系统调用申请内存代价昂贵,涉及到用户态和核心态的转换.
函数malloc()和calloc()都可以用来分配动态内存空间,但两者稍有区别。
malloc()函数有一个参数,即要分配的内存空间的大小:
Void *malloc(size_t size);
calloc()函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小:
void *calloc(size_t numElements,size_t sizeOfElement);
如果调用成功,函数malloc()和calloc()都将返回所分配的内存空间的首地址。
malloc() 函数和calloc()函数的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之,如果这部分内存空间曾经被分配、释放和重新分配,则其中可能遗留各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常运行,但经过一段时间后(内存空间已被重新分配)可能会出现问题。
calloc() 函数会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那么这些元素将保证会被初始化为零;如果你是为指针类型的元素分配内存,那么这些元素通常(但无法保证)会被初始化为空指针;如果你是为实数类型的元素分配内存,那么这些元素可能(只在某些计算机中)会被初始化为浮点型的零。
malloc() 函数和calloc()函数的另一点区别是calloc()函数会返回一个由某种对象组成的数组,但malloc()函数只返回一个对象。为了明确是为一个数组分配内存空间,有些程序员会选用calloc()函数。但是,除了是否初始化所分配的内存空间这一点之外,绝大多数程序员认为以下两种函数调用方式没有区别:
calloc(numElements ,sizeOfElement);
malloc(numElements *sizeOfElement) ;
需要解释的一点是,理论上(按照ANSIC标准)指针的算术运算只能在一个指定的数组中进行,但是在实践中,即使C编译程序或翻译器遵循这种规定,许多C程序还是冲破了这种限制。因此,尽管malloc()函数并不能返回一个数组,它所分配的内存空间仍然能供一个数组使用(对realloc()函数来说同样如此,尽管它也不能返回一个数组)。
总之,当你在calloc()函数和malloc()函数之间作选择时,你只需考虑是否要初始化所分配的内存空间,而不用考虑函数是否能返回一个数组。
当程序运行过程中malloc了,但是没有free的话,会造成内存泄漏.一部分的内存没有
被使用,但是由于没有free,因此系统认为这部分内存还在使用,造成不断的向系统申请内
存,是的系统可用内存不断减少.但是,内存泄漏仅仅指程序在运行时,程序退出时,OS将回
收所有的资源.因此,适当的重起一下程序,有时候还是有点作用.

2007-09-20 22:37
静思
Rank: 3Rank: 3
来 自:沈阳
等 级:新手上路
威 望:8
帖 子:630
专家分:0
注 册:2006-2-28
收藏
得分:0 
如果内存分配的方式是栈方式,遵循先进后出的原则,没有内存碎片产生,程序员无需干预内存的分配,而堆分配的方式需要程序员的干预,而且会产生内存碎片,从这个角度说我们是不是应该尽量用栈的内存分配方式?期盼高手回答

[此贴子已经被作者于2007-9-21 8:40:10编辑过]



英者自知,雄者自胜
2007-09-20 22:50
dct24
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2007-7-6
收藏
得分:0 
这个问题我夜碰到过了
理解没有错,是编译器的原因,因为在编译char * a = "abc"时, 已经把它当作一个常量了,相当于const类型,所以无论对它的修改都会被视为错误,而char a[]在编译时没有把它当作常量,因此仍可对它修改
2007-09-21 14:49
shaddy
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2007-6-18
收藏
得分:0 
你们说的都不对;


char* a = "abc" 开辟一块内存 存放字符串 abc/0 并把这个字符串的首地址存放到 a 指针中,而且它开辟的内存是只读(跟常量差不多)的所以 a[1]='k' 是不对的 因为这个字符串是只读的。其实这句跟 const char * a="abc" 是一样的(我感觉).


char a[]="abc" 是开辟一块内存存放 abc/0 这块内存首地址就是 &a 。并且 它不是只读的所以可以修改。注意这快内存首地址是 &a 。
2007-09-21 18:52
雨中飞燕
Rank: 3Rank: 3
等 级:禁止访问
威 望:8
帖 子:2200
专家分:0
注 册:2007-8-9
收藏
得分:0 
以下是引用shaddy在2007-9-21 18:52:13的发言:
你们说的都不对;


char* a = "abc" 开辟一块内存 存放字符串 abc/0 并把这个字符串的首地址存放到 a 指针中,而且它开辟的内存是只读(跟常量差不多)的所以 a[1]='k' 是不对的 因为这个字符串是只读的。其实这句跟 const char * a="abc" 是一样的(我感觉).


char a[]="abc" 是开辟一块内存存放 abc/0 这块内存首地址就是 &a 。并且 它不是只读的所以可以修改。注意这快内存首地址是 &a 。

你没有把我说的当一回事(37楼),还有请不要把\0都写错



by 雨中飞燕 QQ:78803110 QQ讨论群:5305909

[url=http://bbs.bc-cn.net/viewthread.php?tid=163571]请大家不要用TC来学习C语言,点击此处查看原因[/url]
[url=http://bbs.bc-cn.net/viewthread.php?tid=162918]C++编写的Windows界面游戏[/url]
[url=http://yzfy.org/]C/C++算法习题(OnlineJudge):[/url] http://yzfy.org/

[此贴子已经被作者于2007-9-21 19:09:45编辑过]

2007-09-21 19:08
wzhgzj
Rank: 1
等 级:新手上路
帖 子:108
专家分:0
注 册:2007-9-6
收藏
得分:0 
顶42楼的!

命运在我手中
2007-09-26 01:09
远去的列车
Rank: 1
等 级:新手上路
威 望:2
帖 子:205
专家分:0
注 册:2007-8-7
收藏
得分:0 
char *s = "abc";

s 指向常量字符串

这样改:
int main()
{
char *s = (char *)malloc(4);

if (s == NULL)
{
printf("....");
exit(1);
}

strcpy(s, "abc");
s[1] = 'k'; //或 *(s+1) = 'k';
pritf("%s", s); // 输出 akc

free(s);
return 0;
}

[此贴子已经被作者于2007-9-26 15:31:24编辑过]


C++学习
2007-09-26 15:12
远去的列车
Rank: 1
等 级:新手上路
威 望:2
帖 子:205
专家分:0
注 册:2007-8-7
收藏
得分:0 
char a[] = "abc";
char b[5];
char *p;

b = a; //错误,用 strcpy(b,a);

p = a;
//正确,将数组 a 的地址赋给指针 p

p = (char *)malloc(sizeof(char) * (strlen(a)+1));
strcpy(p,a); //正确,将 a 里的内容复制给 p, 跟 p = a; 不一样哦

C++学习
2007-09-26 15:38
静思
Rank: 3Rank: 3
来 自:沈阳
等 级:新手上路
威 望:8
帖 子:630
专家分:0
注 册:2006-2-28
收藏
得分:0 
多谢各位的参与,本人对这个也差不多理解了..

英者自知,雄者自胜
2007-09-26 17:02
快速回复:[讨论]char* a = "abc" 和 char a[] = "abc" 之间的区别 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014938 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved