如何在C中初始化堆中的只读内存位置?

如何在C中初始化堆中的只读内存位置?,c,C,考虑以下代码: #include<stdio.h> int main() { const char* c = malloc(1); *c = 'a'; printf("%c\n",*c); } 如何在堆内存中初始化常量变量?堆中没有只读位置。请参见Steve Summents的答案,以获得良好的解释 无论你做什么来实现这一点,都要由你来确保你不会在这些地方写作。你可以很好地保护自己,但不是100% 你可以这样做: char * x = malloc(1);

考虑以下代码:

#include<stdio.h>

int main()
{
    const char* c = malloc(1);
    *c = 'a';
    printf("%c\n",*c);
}

如何在堆内存中初始化常量变量?

堆中没有只读位置。请参见Steve Summents的答案,以获得良好的解释

无论你做什么来实现这一点,都要由你来确保你不会在这些地方写作。你可以很好地保护自己,但不是100%

你可以这样做:

char * x = malloc(1);
*x = 'a';
const char * c = x;
// Promise to not use the pointer x again
printf("%c\n",*c);
或者,如果您更愿意将其封装一点:

const char * init()
{
    char* c = malloc(1);
    if(c == NULL) { // Always check if allocation is successful
        // Code for error handling
    }
    *c = 'a';
    return c;
}

int main()
{
    const char * p = init();
    printf("%c\n",*p);
}
请注意,仍然允许在不使用常量的情况下写入
char*p=init()
,这样确实可以写入
*p='a'
,但您至少会触发此警告:

warning: initialization discards ‘const’ qualifier from pointer target 
type [-Wdiscarded-qualifiers]
     char * p = init();
这里需要注意的另一件事是,如果调用
free(p)
,您将收到警告,因为
p
是一个
const
指针。如果您将
p
声明为一个
char*
,您将摆脱此警告,但您将得到我在上一段中提到的警告。(当然,通过将其声明为const,您也将失去所有试图获得的写保护)

要解决这个问题,您可以使用
free((char*)p)


作为旁注,如果您想确保永远不会更改
p
指向的位置,那么可以像这样声明
const char*const p=init()
。这样就不可能使
p
指向代码后面的其他内容。

堆中没有只读位置。请参见Steve Summents的答案,以获得良好的解释

无论你做什么来实现这一点,都要由你来确保你不会在这些地方写作。你可以很好地保护自己,但不是100%

你可以这样做:

char * x = malloc(1);
*x = 'a';
const char * c = x;
// Promise to not use the pointer x again
printf("%c\n",*c);
或者,如果您更愿意将其封装一点:

const char * init()
{
    char* c = malloc(1);
    if(c == NULL) { // Always check if allocation is successful
        // Code for error handling
    }
    *c = 'a';
    return c;
}

int main()
{
    const char * p = init();
    printf("%c\n",*p);
}
请注意,仍然允许在不使用常量的情况下写入
char*p=init()
,这样确实可以写入
*p='a'
,但您至少会触发此警告:

warning: initialization discards ‘const’ qualifier from pointer target 
type [-Wdiscarded-qualifiers]
     char * p = init();
这里需要注意的另一件事是,如果调用
free(p)
,您将收到警告,因为
p
是一个
const
指针。如果您将
p
声明为一个
char*
,您将摆脱此警告,但您将得到我在上一段中提到的警告。(当然,通过将其声明为const,您也将失去所有试图获得的写保护)

要解决这个问题,您可以使用
free((char*)p)


作为旁注,如果您想确保永远不会更改
p
指向的位置,那么可以像这样声明
const char*const p=init()
。这就不可能让
p
指向代码后面的其他内容。

首先,要明白,堆中没有“只读位置”这样的东西。堆是100%可写的
malloc()
定义为返回
void*
。允许您写入
malloc
返回的指针指向的数据

但是第二件要理解的事情是,
const
也不一定意味着“只读”

只读内存是一种东西,它通常会被
const
指针指向,如果(尽管有任何
const
指针)您试图写入只读内存,通常会出现某种异常

但是您可以拥有由非
const
指针指向的只读内存,也可以拥有指向可写内存的
const
指针

因此,
const
真正的意思是“我保证不写入此内存”或“我声明我不打算写入此内存”,并附加规定“如果我不小心尝试写入此内存,我希望编译器给我编译时错误。”

如果您有一个普通的
const
指针,您可以初始化它一次。你可以这样说

const str1[] = "hello";

即使以后尝试更新字符串,如

*str1 = 'x';    /* WRONG */

这将失败。(您可以将其视为
const
限定数据的“初始化异常”


但正如您所发现的,通过调用
malloc
初始化的
const
指针没有例外。如果您想从
malloc
中获取一些内存,并初始化一次,然后保证以后不修改它,并且如果您想让编译器为您强制执行此承诺,您不能这样做首先,除非您使用注释和中描述的双指针解决方法,否则请理解“堆中没有只读位置”。堆是100%可写的。
malloc()
定义为返回
void*
。允许您写入
malloc
返回的指针指向的数据

但是第二件要理解的事情是,
const
也不一定意味着“只读”

只读内存是一种东西,它通常会被
const
指针指向,如果(尽管有任何
const
指针)您试图写入只读内存,通常会出现某种异常

但是您可以拥有由非
const
指针指向的只读内存,也可以拥有指向可写内存的
const
指针

因此,
const
真正的意思是“我保证不写入此内存”或“我声明我不打算写入此内存”,并附加规定“如果我不小心尝试写入此内存,我希望编译器给我编译时错误。”

如果你有一个序号