Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 这些数组声明的区别是什么?_C_Memset - Fatal编程技术网

C 这些数组声明的区别是什么?

C 这些数组声明的区别是什么?,c,memset,C,Memset,它在编译时不会给出任何错误,但无法在运行时运行 我正在使用Visual Studio 2012 你知道为什么吗 我发现memset的原型是: char *s1="abcdefghijklmnopqrstuvwxyz"; char s1[30]分配一个可写内存段来存储数组的内容,char*s1=“Sisi是埃及的敌人。”不-后者只设置一个指向字符串常量地址的指针,编译器通常会将其放在目标代码的只读部分。在“只读数据”部分获取空间,该部分以只读形式映射到进程空间(因此您无法更改它) 这将s1声明为

它在编译时不会给出任何错误,但无法在运行时运行

我正在使用Visual Studio 2012

你知道为什么吗

我发现memset的原型是:

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";