几个有关内存的实例分析:
实例 1:
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 char string[10],str1[10];
7 for(int i = 0;i < 10;i++)
8 {
9 str1 ='a';
10 }
11 strcpy(string,str1);
12 return 0;
13 }
运行结果:在编译阶段不能通过,因为在本函数中str1保存的是一个数组的首地址。不能做为左值,因为我们其实是可以把它作为一个指针常量;既然是常量当然就不能够作为左值,被其他值进行赋值。
实例 1(修改过上述错误之后)
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(void)
5 {
6 char string[10],str1[10];
7 for(int i = 0;i < 10;i++)
8 {
9 str1[i] ='a';
10 }
11 strcpy(string,str1);
12 return 0;
13 }
运行结果:编译阶段不会报错,但是在运行之后会有以下错误提示:
Abort trap: 6
该提示表示中断异常,分析一下为什么会有这种异常出现:首先该函数可以进行正常的编译,也就是说在编译阶段没有错误,而是在运行阶段;在函数开始阶段我们可以看到定义了两个字符串数组,str1和string都是定义了十个元素的数组,所以它们的内存空间就只有十个元素。当进行for循环给str进行赋值的时候,将str中的十个元素都赋值成了'a',也就是说字符串数组中没有结束符'\0'。当调用strcpy函数时,string函数接收str1数组,当十个元素都接收完,strcpy函数没有遇到'\0',所以会继续沿着str1之后的内存地址进行拷贝直到遇见'\0';这样string的内存中所存储的值就远远超过了定义的十个元素,这就击穿了string的内存去;也就是我们说的栈溢出。
实例 2:
#include <stdio.h>
int main(void)
{
char *ptr = "hello";
*ptr = 'T';
printf("%s\n",ptr);
return 0;
}
运行结果:
再编译阶段会直接报错,错误分析:char *ptr = “hello”这条语句是在main函数中定义一个变量char *ptr(ptr存在于栈内存中),并且给其进行赋值一个自负串,该字符串存在于内存中的data区,该区域的内容是只读的;这就导致了在下面的语句*ptr = ‘T’;是错误的,因为我们不可以对一块只读的内存区域进行赋值操作。
实例 3:
1 #include <stdio.h>
2 #include <string.h>
3
4 void getMemory(char *p)
5 {
6 p = (char *)malloc(100);
7 }
8
9 void test(void)
10 {
11 char *str = NULL;
12 getMemory(str);
13 strcpy(str,"hello");
14 printf("str is %s\n",str);
15 }
16 int main(void)
17 {
18 test();
19 return 0;
20 }
运行结果:
Segmentation fault: 11
运行阶段出现这种错误;分析一下错误原因,在test函数调用getMemory函数的时候,我们传进去一个参数str,str是一个char*类型的变量;当我们调用一个函数的时候传递的是一个变量,那么这个变量就是一个值传递,由于我们对字符串指针str进行了初始化另其指向空,那么它的内容就是0x0000000,即指向一个空地址。当传递到getMemory函数中以后我们进行了也只是将0这个地址带给了p。当p内存申请,也仅仅是p申请了内存,由于是值传递,所以并不能将地址传递给str,也就是说str这个0x000000这个值并没有改变,故在test函数中str其实是一块空的内存,并不能将“hello”这个字符串拷贝给str(指向NULL的地址,不能进行赋值)。
实例4:
1 #include <stdio.h>
2
3 char *GetMemory(void)
4 {
5 char p[] = "hello would";
6 return p;
7 }
8
9 int main(void)
10 {
11
12 char *str = NULL;
13 str = GetMemory();
14 printf("the str is %s",str);
15 return 0;
16 }
运行结果:
运行出错,因为GetMemory函数返回了一个栈里面的内存,当函数返回之后,该内存已经不受保护了(同时也就是说明了我们没有权限进行操作该区域的内存空间了)。