c/c++语言开发共享C中的指针数组和只读存储器

我正在学习C编程语言,并且在理解指针,数组和只读存储器之间的微小差异时遇到了困难。 我正在使用以下示例:

char *myCards = "JQK"; 

根据我的理解,这行代码完成的是它在内存的只读段中创建一个空终止字符串,可通过char指针myCards 。 这意味着我能够编译以下内容,但由于字符串的不变性而会收到错误:

 *myCards = 'A'; 

我试图使用一组int来实现类似的function; 但是,如果可能的话,我完全不确定如何创建这个数组并将其放在内存的只读部分。

我知道我可以使用const关键字并创建一个数组,如下所示:

 const int myInts[] = {3, 6, 1, 2, 3, 8, 4, 1, 7, 2}; 

但是,我可以在此数组初始化后直接执行以下操作:

 printf("First element of array: %in", myInts[0]); int *myIntsPtr = myInts; *myIntsPtr = 15; printf("First element of array: %in", myInts[0]); 

我能够通过创建指向它的指针来改变数组的第一个元素,这意味着该数组永远不会被放入只读存储器中。

基本上我一直试图弄清楚我如何能够声明这个int数组,以便它在只读存储器中类似于"JQK" 。 任何见解都有帮助。 谢谢。

    好的,首先要了解这一点,重要的是要知道C中的const不需要对只读内存做任何事情。 对于C,没有部分这样的东西。 const只是一个契约,它表达的意图是事物确实是不变的。 这意味着编译器/链接器可以将数据放在只读部分,因为程序员保证它不会改变。 但它没有必要

    其次,字符串文字转换为一个常量的char数组,其中0隐式附加。 请参阅Peter Schneider在这里的注释:它不是正式的 const(因此编译器不会在你使用非const指针时警告你),但它应该是。

    结合这个,下面的代码在我的系统上使用gd在Linux amd64上进行段错误,因为gcc确实将数组放在只读部分:

     #include  const int myInts[] = {3, 6, 1, 2, 3, 8, 4, 1, 7, 2}; int main(void) { printf("First element of array: %in", myInts[0]); int *myIntsPtr = myInts; *myIntsPtr = *(myIntsPtr + 1); printf("First element of array: %in", myInts[0]); return 0; } 

    请注意,在您使用非const指针指向const数组的行中还有一个编译器警告。

    顺便说一下,如果用gcc声明函数内部的数组,那么相同的代码就可以工作,因为那样,数组本身就是在堆栈上创建的。 你仍然得到警告,代码仍然是错误的。 这是C在这里如何实现的技术细节 。 与字符串文字的区别在于它是一个匿名对象(char数组没有标识符),并且在任何情况下都具有静态存储持续时间。


    编辑以解释字符串文字的作用:以下代码是等效的:

     int main(void) { const char *foo = "bar"; } 

     const char ihavenoname_1[] = {'b', 'a', 'r', 0}; int main(void) { const char *foo = ihavenoname_1; } 

    所以,简短的故事,如果你想让gcc将数据放在一个只读部分,请用静态存储持续时间(在函数之外)声明它为const 。 其他编译器可能表现不同。

    我同意菲利克斯帕尔曼。 函数中的数组存储在堆栈中,即使它是const,也可以使用适当的强制转换来修改它。 这是我用MS-VC ++(ebp是堆栈指针)所得到的:

     const int test [ 5 ] = { 0, 1, 2, 3, 4 }; 00309598 mov dword ptr [ebp-1Ch],0 0030959F mov dword ptr [ebp-18h],1 003095A6 mov dword ptr [ebp-14h],2 003095AD mov dword ptr [ebp-10h],3 003095B4 mov dword ptr [ebp-0Ch],4 ( ( int* ) test ) [ 1 ] = 0; 003095BB mov dword ptr [ebp-18h],0 

    现在,在函数中定义数组,但这次是static const ,或者将其定义为const全局变量……我们对两个测试都有相同的结果:数组现在在数据段中(使用地址而不是比ebp)但仍然可以修改:

     static const int test [ 5 ] = { 0, 1, 2, 3, 4 }; ( ( int* ) test ) [ 1 ] = 0; 01449598 mov dword ptr [test+4 (145ECACh)],0 

    使用gcc,您将拥有只读内存中的数据,但正如Felix所说,它并不保证:例如,如果您使用MS-VC,您仍然可以修改它。

      以上就是c/c++开发分享C中的指针数组和只读存储器相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/559570.html

      (0)
      上一篇 2021年1月27日
      下一篇 2021年1月27日

      精彩推荐