在C语言中定义一个动态的只读数组

4

在C语言中如何定义一个动态只读整数数组?

我知道我们可以使用修饰符“const”和“static”来分配静态只读数组。但是如何在动态数组的情况下做到相同呢?


相同的代码:const int *arr = malloc(n * sizeof(*arr));,但这根本没有意义。 - David Ranieri
这并没有太多意义。你需要在某个时候将数据写入数组中。但是,你可以定义一个变量指向数据而不允许修改。 - grek40
我认为你忽略的问题是,你把数组填充为读写数组,然后将其作为“const”传递给任何需要防止修改的函数(在此读取一些内容)。 - David C. Rankin
2个回答

3
你可以使用 const 限定符指向已经创建的非 const 数组:
#include <stdio.h>
#include <stdlib.h>

int *alloc(int n)
{
    int *arr = malloc(n * sizeof(*arr));

    for (int i = 0; i < n; i++) {
        arr[i] = i;
    }
    return arr;
}

int main(void)
{
    const int *arr = alloc(5);

    arr[3] = 5; /* error */
    return 0;
}

正如hvd所说,可以通过声明另一个指针ptr来修改“arr”:ptr = arr; 然后 *ptr = 64; - Abhinay B
1
当然这不是一个错误而是一个警告,const在C语言中并不意味着“只读”,但在你提问之前你已经知道了,对吧? - David Ranieri
1
当然!我知道在C语言中const并不意味着只读。这也是我提出问题的原因,想知道是否有其他方法可以实现只读。对于变量,我们可以使用const static来使其只读。但我不知道如何在动态数组中实现相同的功能。感谢您的帮助! - Abhinay B
1
@AbhinayB:“我们可以使用const static一起使变量只读”你确定吗?我会说不是。此外,在C中,static与任何常数无关。 - alk
1
@AbhinayB:当然可以在const后面加上static,但是使用static并不会改变常量的性质。如果GCC这样做,那么这是GCC特有的行为。它不受C标准支持 - alk
显示剩余6条评论

3
没有标准的方法可以将动态分配的内存定义为const。这样做没有太多意义,因为除了使用calloc将其初始化为零之外,您无法对动态分配的内存使用初始化。C语言根本没有用于将内存初始化为其他任何内容的标准库函数。它要求您使用赋值来代替,但这永远无法与const一起使用。
您可以将指向动态分配内存的指针声明为const,但如果这样做,用户可以(就语言标准而言)强制转换掉const并修改数据。
理论上来说可能还不够好,但实际上已经足够了。代码中强制转换掉const以修改数据,特别是以对调用方不清楚的方式进行修改的情况非常罕见。

“用户被允许(就语言标准而言)放弃const”,但这样做仍然会引发未定义的行为,不是吗? - alk
@alk:如果指向const限定类型的指针最初来自非const限定类型的指针,则它不是未定义的。您始终可以将指针转换回其原始类型并使用它。因此,您可以从malloc获取一些内容,对其进行初始化,然后将指向const限定类型的指针传递给其他例程,但是它们可能会合法地将其强制转换回来。 - Eric Postpischil
@EricPostpischil编辑后,希望不再暗示这样的函数不存在。 - user743382

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接