一个既超级简单又超级复杂的C语言问题:

程序一:#include<stdio.h>#include<stdlib.h>intmain(){char*s;intnLen=100;//malloc申请的空间最多存储... 程序一:
#include<stdio.h>
#include<stdlib.h>

int main()
{
char *s;
int nLen = 100;

// malloc申请的空间最多存储长度为100的字符串
// 最后一个字节存储字符串结尾符
s = (char *)malloc((nLen + 1) * sizeof(char));

gets(s);
puts(s);

free(s);
s = NULL;

return 0;
}
能够运行!
程序二:
#include<stdio.h>
#include<stdlib.h>

int main()
{
char *s;

s = (char *)malloc(sizeof(char));

gets(s);
puts(s);

free(s);
s = NULL;

return 0;
}
不能运行!

程序三:
#include<stdio.h>
#include<stdlib.h>

int main()
{
char *s;
s = (char *)malloc( sizeof(char));
gets(s);
puts(s);
return 0;
}
可以运行!

程序四:
#include<stdio.h>
#include<string.h>
int main()
{
char s[20]="djksafd";
char *str=s;
char s1[2];
strcpy(s1,str);
printf("%s\n",s1);
return 0;
}
不能运行!

程序五:
#include<stdio.h>
#include<string.h>
int main()
{
char s[20]="djksafd";
char *str="hakdshkdsak";
char s1[2];
strcpy(s1,str);
printf("%s\n",s1);
return 0;
}
可以运行!

程序六:
#include<stdio.h>
#include<string.h>
int main()
{
char s[20]="djksafd";
char *str=s;
char s1[20];
strcpy(s1,str);
printf("%s\n",str);
return 0;
}
可以运行!

程序七:
程序一:
#include<stdio.h>
#include<stdlib.h>

int main()
{
char *s;
int nLen = 100;

// malloc申请的空间最多存储长度为100的字符串
// 最后一个字节存储字符串结尾符
s = (char *)malloc((nLen + 1) * sizeof(char));

gets(s);
puts(s);

free(s);
s = NULL;

return 0;
}
能够运行!
程序二:
#include<stdio.h>
#include<stdlib.h>

int main()
{
char *s;

s = (char *)malloc(sizeof(char));

gets(s);
puts(s);

free(s);
s = NULL;

return 0;
}
不能运行!

程序三:
#include<stdio.h>
#include<stdlib.h>

int main()
{
char *s;
s = (char *)malloc( sizeof(char));
gets(s);
puts(s);
return 0;
}
可以运行!

程序四:
#include<stdio.h>
#include<string.h>
int main()
{
char s[20]="djksafd";
char *str=s;
char s1[2];
strcpy(s1,str);
printf("%s\n",s1);
return 0;
}
不能运行!

程序五:
#include<stdio.h>
#include<string.h>
int main()
{
char s[20]="djksafd";
char *str="hakdshkdsak";
char s1[2];
strcpy(s1,str);
printf("%s\n",s1);
return 0;
}
可以运行!

程序六:
#include<stdio.h>
#include<string.h>
int main()
{
char s[20]="djksafd";
char *str=s;
char s1[2];
strcpy(s1,str);
printf("%s\n",str);
return 0;
}

不能运行!

这是怎么回事?请专家解答!
程序七:
#include<stdio.h>
#include<string.h>
int main()
{
char s[20]="djksafd";
char *str=s;
char s1[20];
strcpy(s1,str);
printf("%s\n",s1);
return 0;
}
可以运行!
展开
 我来答
匿名用户
2012-04-03
展开全部
楼上的回答都很高深,没看明白。把我的理解也说下:
C语言中的字符串(C++中叫做C风格字符串),他的一个最大特点就是以NULL结尾。所以他的存储空间比实际字符数多一个。
C风格字符串,在C中是标准库类型,不是C的内置类型。他的内存管理由程序负责。
内存管理不好会产生溢出。
malloc和free是C语言中用来管理内存(或者叫堆)的。
free释放内存空间。如果不释放会产生内存(堆)耗尽。
字符数组复制给字符数组,会产生溢出(数组对存储空间大小有要求)。
C语言中的字符指针在内存中是线性存储的,他将一块连续的区域(直到出现NULL为止)做为一个字符串。没有存储空间大小的要求。 字符数组复制给字符指针,或字符指针复制给字符指针。不会产生溢出。
动态创建的数组(返回指向新分配数组第一个元素的指针,可见本质是一个指针。),当释放时会报错(释放时释放的是空间,当然有存储空间大小要求)。
4、char s[20]="djksafd";
char *str=s;//对str进行解引用后是数组s。
5、char s[20]="djksafd";
char *str="hakdshkdsak";//对str解引用后是C风格字符串
追问
还是没说到点子上,哎!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
shine1991
科技发烧友

推荐于2016-03-12 · 智能家居/数码/手机/智能家电产品都懂点
知道顶级答主
回答量:4.7万
采纳率:82%
帮助的人:2.3亿
展开全部
除程序1外,其余的本质上讲都是有问题的,不管他可不可以通过编译,可不可以“运行”

程序1没什么好解释的,唯一要注意的是不要输入超过100个字符

程序2和3,分配的字节数过小,而程序3之所以看似能“运行”是因为他没有free函数,但是当输入的字符比较多时,比如说多于二三十个字符时,你就会显示的看到,系统报错

程序4,不用运行,根本就是逻辑上有问题
char s1[2];
strcpy(s1,str);
最基本的strcpy函数的第一个参数,是一个指向足够大空间的指针,以容纳第二个参数指向的内容,这个就根本不满足

程序5同2,3的道理,把字符数一加多,就会有问题

程序6和4完全是一个东西

总之,lz都是在运用C编译器不对越界进行检查的特性乱来而已,本质上都是不可行的,且不具有可移植性,如果采用对越界进行较为严格检查的编译器,立马会报错,比如VS2010

最后给个忠告,不要没事做这种无意义的实验
追问
你说的我都知道!!!我想知道根本原因!
追答
MSDN上关于malloc的部分有以下注意点

Remarks

The malloc function allocates a memory block of at least size bytes. The block may be larger than size bytes because of space required for alignment and maintenance information.

也就是说malloc,由于内存对齐和存储维护信息的关系,实际申请的内存空间数可能是大于申请时的size数量的,但是无论如何也绝不应该越界

同时这也正是为什么程序2中会在free的位置上报错的原因,显然由于越界的关系,malloc的相关信息被覆盖了,导致free出现的问题

如果还要再深究的,那就要讲到malloc的实现,以及不同操作系统对于内存管理机制的原理与实现上来了

我承认讲这个的话,就远超我的能力范围了,你要找大神级别的人去问了
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
xiaowei01357
2012-04-03 · TA获得超过241个赞
知道小有建树答主
回答量:125
采纳率:0%
帮助的人:90.6万
展开全部
对于程序2
malloc分配内存的时候,这片内存的结尾会有个标记,因为他只分配了一个字符的空间,也就是一个字节,所以他在输入一个字符的时候,实际上有两个字符,还有个回车,回车把这片内存的结束标记给占据了,所以释放的时候不能判别了,所以就报内存错误了。如果直接回车就不会有事了。
程序4和程序6不是一样的吗,不过我这边怎么没事,没有错啊
追问
大哥注意看问题补充!因为网速不好,搞的我基本把所有程序都复制了2遍才粘贴,所以才会这样,sorry!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
ks511kisen
2012-04-03
知道答主
回答量:12
采纳率:0%
帮助的人:7万
展开全部
前几个程序没发现什么问题,不知道你用的是什么环境,我帮你运行了下,上面所有你说不能运行的程序都是可以被编译(我用的是DEV C++),你可以去试试。。。
你最后一个程序char *str=s这样赋值是不行的,很容易出错,你可以改下
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char s[20]="djksafd";
char *str;
char s1[20];
str=(char*)malloc(sizeof(char));
strcpy(str,s);
strcpy(s1,str);
printf("%s\n",str);
getchar();
return 0;
}
追问
这些程序都是我的试验品,是我刻意这样编的,目的是搞清楚其局限性,这样才能更好地运用这些库函数!另外,能编译并不代表正确,否则我也不会多此一问了。这个问题恐怕不是单靠基本的C语言就能解决的,可能涉及到汇编原理和储存原理!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
beddy1
2012-04-03 · TA获得超过1988个赞
知道大有可为答主
回答量:2271
采纳率:0%
帮助的人:2182万
展开全部
不能运行的都是因为内存访问越界了,使用字符指针操作字符串的时候一定要确保你的指针指向的空间足够放下字符串。
追问
既不仔细看程序,也没用VC6.0运行,就回答!打酱油也不能这样啊!!!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(4)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式