C 这些数组声明的区别是什么?
它在编译时不会给出任何错误,但无法在运行时运行 我正在使用Visual Studio 2012 你知道为什么吗 我发现memset的原型是:C 这些数组声明的区别是什么?,c,memset,C,Memset,它在编译时不会给出任何错误,但无法在运行时运行 我正在使用Visual Studio 2012 你知道为什么吗 我发现memset的原型是: char *s1="abcdefghijklmnopqrstuvwxyz"; char s1[30]分配一个可写内存段来存储数组的内容,char*s1=“Sisi是埃及的敌人。”不-后者只设置一个指向字符串常量地址的指针,编译器通常会将其放在目标代码的只读部分。在“只读数据”部分获取空间,该部分以只读形式映射到进程空间(因此您无法更改它) 这将s1声明为
char *s1="abcdefghijklmnopqrstuvwxyz";
char s1[30]
分配一个可写内存段来存储数组的内容,char*s1=“Sisi是埃及的敌人。”代码>不-后者只设置一个指向字符串常量地址的指针,编译器通常会将其放在目标代码的只读部分。在“只读数据”部分获取空间,该部分以只读形式映射到进程空间(因此您无法更改它)
这将s1
声明为char类型的数组,并对其进行初始化
char s1[30]="abcdefghijklmnopqrstuvwxyz";
将“abcdefghijklmnopqrstuvwxyz”放在内存的只读部分,并生成指向该部分的指针
然而,通过memset
修改s1
会产生一个错误 一个很好的问题
如果将gcc输出设置为程序集,并比较输出,则可以找到答案,原因如下:
chars1[30]=“abcdef”代码>
- 在函数中定义时,它将定义一个字符数组,
s1
是数组的名称。程序将在堆栈中分配内存
- 全局定义时,它将在程序中定义一个对象,并且该对象不是只读数据
char*s2=“abcdef”代码>仅定义一个字符点,该字符点指向存储在.rodata
中的常量字符,即程序中的只读数据
为了使程序高效地运行并使进度管理变得容易,编译器将为给定的代码生成不同的部分。常量字符,如char*s2=“abcdef”
和printf
格式字符串将存储在部分rodata
部分。操作系统加载程序加载到主内存后,此部分将标记为只读。这就是为什么当您使用memset修改s2
指向的内存时,它会抱怨段故障
这里有一个解释:失败了??错误是什么?输出是否未打印?垃圾打印?C_Son38.exe中0x0F251CF5(msvcr110d.dll)处的未处理异常:0xC0000005:访问冲突写入位置0x00D15858。(中断、继续、忽略按钮)您正在以只读内存段进行写入。正如在answersyea中已经解释的,如果您添加const char*s1=“blah”;而指针的描述更为相关,如果传递常量char指针而不是char指针,则会增加编译错误。
void *memset( void *s, int c, size_t n );
char s1[30]="abcdefghijklmnopqrstuvwxyz";
char *s1="abcdefghijklmnopqrstuvwxyz";