指针数组和C中的只读内存 [英] Pointers Arrays and Read Only Memory in C
问题描述
我正在学习C编程语言,并且在理解指针,数组和只读存储器之间的细微差别时遇到了困难.我正在使用以下示例:
I am learning the C programming language and am running into difficulties in understanding the minute differences between pointers, arrays and read only memory. I am working with the following example:
char *myCards = "JQK";
据我了解,这行代码完成的工作是,它在可通过char指针myCards
访问的只读存储区中创建了一个以空终止的字符字符串.这意味着我能够编译以下内容,但由于字符串的不可变性而会收到错误:
From what I understand what this line of code accomplishes is it creates a null terminated string of characters in a read only section of memory that is accessible via the char pointer myCards
. This means that I am able to compile the following but would receive an error due to the immutability of the string:
*myCards = 'A';
我正在尝试使用整数数组来实现类似的功能;但是,我完全不确定如何创建此数组并将其放置在内存的只读部分中.
I am trying to achieve a similar functionality using an array of ints; however, I am not at all certain on how to create this array and place it in a read only section of memory if at all possible.
我知道我可以使用const
关键字并按如下方式创建一个数组:
I know that I can use the const
keyword and create an array as follows:
const int myInts[] = {3, 6, 1, 2, 3, 8, 4, 1, 7, 2};
但是,在此数组初始化之后,我能够直接执行以下操作:
However, I am able to do the following, directly after this array initialization:
printf("First element of array: %i\n", myInts[0]);
int *myIntsPtr = myInts;
*myIntsPtr = 15;
printf("First element of array: %i\n", myInts[0]);
我能够通过创建指向数组的第一个元素来更改该数组的第一个元素,这表明该数组从未被置于只读存储器中.
I was able to alter the first element of the array by creating a pointer to it, implying that this array was never placed into read only memory.
基本上,我一直试图找出如何声明此int数组,以便使其位于类似于"JQK"
的只读内存中.任何见解都是有帮助的.谢谢.
Basically I am stuck on trying to figure out how I am able to declare this int array so that it is in read only memory similar to "JQK"
. Any insight is helpful. Thank you.
推荐答案
好,首先要了解这一点,重要的是要知道C中的const
不必对只读内存做任何事情.对于C,没有诸如section之类的东西. const
仅仅是一个合约,它表达的意图是某些东西确实是恒定的.这意味着编译器/链接器 可以将数据放置在只读区域中,因为程序员保证数据不会更改.但是,它没有.
Ok, first to understand this, it's important to know that const
in C doesn't have to do anything with read-only memory. For C, there is no such thing as sections. const
is merely a contract, it's expressing the intention that something is indeed constant. This means a compiler/linker can place data in a read-only section because the programmer assured it won't change. It doesn't have to, though.
第二,字符串文字会转换为char
的常量数组,并隐式附加0
.请在此处查看Peter Schneider的评论:它不是形式上 const(因此,当您使用非const指针时,编译器不会警告您),但它应该
Second, a string literal translates to a constant array of char
s with 0
implicitly appended. See Peter Schneider's comment here: it is not formally const (so the compiler won't warn you when you take a non-const pointer to it), but it should be.
与此相结合,我的系统上的以下代码段在Linux amd64上与gcc一起在我的系统上出现,因为gcc
确实将数组放置在只读段中:
Combining this, the following code segfaults on my system with gcc on Linux amd64, because gcc
indeed places the array in a read-only section:
#include <stdio.h>
const int myInts[] = {3, 6, 1, 2, 3, 8, 4, 1, 7, 2};
int main(void)
{
printf("First element of array: %i\n", myInts[0]);
int *myIntsPtr = myInts;
*myIntsPtr = *(myIntsPtr + 1);
printf("First element of array: %i\n", myInts[0]);
return 0;
}
请注意,在将非const指针指向const数组的行中,还会出现编译器警告.
Note there is also a compiler warning in the line where you take a non-const pointer to the const array.
顺便说一句,如果您使用gcc
在函数中声明数组,则相同的代码将起作用,这是因为然后,数组本身是在堆栈上创建的.仍然会收到警告,代码仍然是错误的.这是有关如何在此处实现C的技术细节.与字符串文字的不同之处在于,它是一个匿名对象(char数组没有标识符),并且在任何情况下都具有静态存储期限.
Btw, the same code will work if you declare the array inside your function with gcc
, that's because then, the array itself is created on the stack. Still you get the warning, the code is still wrong. It's a technical detail of how C is implemented here. The difference to a string literal is that it is an anonymous object (the char array doesn't have an identifier) and has static storage duration in any case.
编辑来解释字符串文字的作用:以下代码是等效的:
edit to explain what a string literal does: The following codes are equivalent:
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
.其他编译器的行为可能有所不同.
So, short story, if you want gcc
to put data in a read-only section, declare it const
with static storage duration (outside of a function). Other compilers might behave differently.
这篇关于指针数组和C中的只读内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!