c语言指针问题,为什么我输入很多个都没有显示错误?
#include "malloc.h"
#include "string.h"
void main(){
char *p;
p=(char *)malloc(sizeof(char));
scanf("%s",p);
printf("%s",p);
} 展开
因为C语言不提供内存越界访问检查机制,p在堆内存上申请了一个char长度空间(注意:malloc实际分配的内存有可能比请求的稍微多一点,但是这个行为是由编译器定义的,所以不能指望它肯定会分配比请求更多的内存)。
你在随后输入一个字符串时候,通过scanf函数读取到p指针指向的内存中,虽然只申请了一个字节空间,但其后的内存因为(通常)不是非法地址,所以也能被操作。
这个错误在实际软件开发时,经常会发生且不容易发现。假如操作的越界内存是一块非法地址,程序将会终止。这个错误在unix/linux系统上称为“段错误”。它提示程序试图访问一个并未分配给程序的内存位置。这还属于比较好的情形,最可怕的是:如果这个越界的地址是一个合法地址(如你的例子中),接下来,如果有其他变量正在使用这块内存,其中的值被无意修改了,并且这种错误很难发现。所以对指针的操作要异常小心。
另外你可以试试,即使定义这个p指针为 char p[1];栈中内存,也能进行错误操作如:
p[-1] = 'l'; //“错误操作”
p[0] = 'o';
p[1] = 'v'; //“错误操作”
p[2] = 'e'; //“错误操作”
char *temp = p;
--temp;
printf("%s\n", p); //打印 ove
printf("%s\n", temp); //将打印 love
是不是要输入几个字符就malloc分配几个char?
或者用p[i]i表示输入的个数?
一般来说,从外部得来的数据(如用户输入,读取文件)都是不可预见内容,所以在程序中得防止可能造成的影响。举例来说,假如分配的内存为 char *p = malloc(16); 十六个字节长,scanf读取后,可能如你示例中读入很多超过16个字符,也有可能没有16个字符。但只要保证最后一个字符是'\0'就不会出现字符串越界输出的情况。以下示例:
char *p = malloc(16); //malloc函数在申请内存后会将申请到的内存清零
scanf("%s", p);
p[15] = '\0';