首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

字符串操作(在内存中读写)的有关问题

2012-04-03 
字符串操作(在内存中读写)的问题?#includestdio.hvoidcopy_string(char*from,char*to){for(*from! \0

字符串操作(在内存中读写)的问题?
#include   <stdio.h>
void   copy_string(char   *from,char   *to)
{
      for(;*from!= '\0 ';from++,to++)
              *to=*from;
      *to= '\0 ';
}
int   main(int   argc,char   *argv[])
{
        char   *str1= "123456789 ";
        char   *str2= "abcdefg ";
        copy_string(str2,str1);
        printf( "%s\n ",str1);
        return   0;
}
(1)以上代码在TC2.0下可以正常通过执行,但在VS2005中不能通过.linux下能编译(gcc),但执行提示段错误!如果把char   *str1该为char   str1[]在VS2005和linux下就都正常了!为什么?
(2)用char   *str定义的字符串好象不能往里写只能读,而用char   str[]定义的字符串就可以读也可以写.如何来判断一个char指针是用char   *定义的还是用char   []来定义的呢?
谢谢了!


[解决办法]
char *str1= "123456789 ";
char *str2= "abcdefg ";
_____________________________________________________
这样定义的字符串存在常量区,是只能读不能改写的。。。
[解决办法]
如果要用指针操作的话  
用malloc动态申请空间
char *p;
p=(char *)malloc(N*sizeof(char));

[解决办法]
copy_string(str2,str1);这个函数在使用时必须保证str2有足够的空间,但是你这里使用的指针,并没有给它分配足够空间,所以不行!
char *str2 = "123456789 ";/* "123456789 "是在常量区,str2本身在栈中,占用sizeof(char *)字节,也就是说str2只是指向常量区,那段空间并不属于它!*/
char str2[100] = "123456789 ";/*栈中分配了100个字节*/

可以使用2种方法:
#define MaxSize 100
1.
char *str1= "123456789 ";
char *str2=(char *)malloc(sizeof(char)*MaxSize);
copy_string(str2,str1);
2.
char *str1= "123456789 ";
char str2[MaxSize]= "abcdefg ";
copy_string(str2,str1);

[解决办法]
或者这样保护一下
BOOL CheckMemWrite(void* pAddress, DWORD dwSize)
{
if(pAddress==NULL||dwSize==0)
return FALSE;
if(IsBadWritePtr(pAddress, dwSize))
return FALSE;
return TRUE;
}

BOOL CheckMemRead(void* pAddress, DWORD dwSize)
{
if(pAddress==NULL||dwSize==0)
return FALSE;
if(IsBadReadPtr(pAddress, dwSize))
return FALSE;
return TRUE;
}

void copy_string(char *from,char *to)
{
if(!CheckMemRead(from, strlen(from)) || !CheckMemWrite(to, strlen(to)))
return;
for(;*from!= '\0 ';from++,to++)
*to=*from;
*to= '\0 ';
}
[解决办法]
TC工作在V86模式下,内存你随便指,随便写都没有关系。Win32工作在保护模式下,有权限检查。
[解决办法]
呵呵,楼主学习的精神令人敬佩:
1、C语言设计时,是为了替代汇编语言开发操作系统使用的,因此强调灵活性。C语言不是强类型的语言,编译器只检查你的代码形式上是否合法,具体操作的是否合法是只有在运行时才会知道的。作为一个C程序员,需要非常清楚的知道自己在干什么。
所以,楼主的这份代码,在TC2.0、和Windows的VS2005/Linux下的GCC都是可以编译通过的。但是运行可能会有问题。
2、在void copy_string(char *from,char *to)函数中,它只知道传进来的是两个指针,根据C语言的语法,函数本身是无法知道传进来的是字符串常量指针还是字符串数组的指针的。所以楼主的第二个问题的答案是否定的。
3、在编程语言中,数据分为常量和变量,常量是只读的,变量是可读、可修改赋值的。char *StrConst= "123456789 "; 是字符串常量,而char StrArray= "123456789 ";是定义了一个字符串变量。不同的操作系统、不同的编译器对于常量和变量的处理措施是允许进行进行特有的优化、保护的。
(1)、TC2.0编译出来的代码是16bit的80X86实模式的代码,变量可以访问、修改整个操作系统所有的内存空间,并且没有对常量进行保护。因此,copy_string函数可以对常量字符串*StrConst= "123456789 "进行写操作。
(2)、在WindowsNT/2000/XP/2003以及Linux等操作系统中,引入了32位保护模式的概念。每个进程都有独立的32位内存地址空间,在一个进程内部,也对代码区和常量进行了保护,任何试图修改常量的值的企图都将引起非法内存访问而被操作系统所禁止。而这种保护的保护对象是由编译器在编译阶段确定、运行时由操作系统负责实施的,所以,您的代码用VS2005/GCC编译可以通过,但是执行时是会被操作系统KILL的。


(3)、为什么可以编译通过?因为在C中,数组的名称即使数组的指针,而函数copy_string只是要求输入参数是字符串指针即可,至于这两个指针在函数copy_string中怎么使用,编译器是不用管也管不了的,因此可以编译通过。
4、相关参考书。以上是本人汇总各位网友的分析,糅合本人的计算机专业知识做的解释,其实还不够严格、科学。若您喜欢刨根问底,建议在学习了计算机本科阶段的操作系统、80X86汇编原理、单片机、编译原理(计算机软件方向、软件工程方向应该会学,计算机应用、计算机通信方向的可能不学编译原理)后,对于Windows操作系统,上海好像电子工业出版社还是机械工业出版社出版过一本Windows2000内存体系结构的书,好像是上交大尤晋元教授编著的,对于Linux的内存体系以及GCC编译器,您有兴趣可以在网上找一下。
5、有句话,叫“敏而好学,不求甚解”。我的理解是,能够根据当前工作任务需要,快速的接纳、学习各种新旧知识,既好学,又不钻牛角尖。当然,如果您能够把GCC的原理和实现代码都研究透的话,您应该可以成为牛人了。我只是个IT民工,所以没有研究透,呵呵。

热点排行