使用 `struct S const char *array[ARG_MAX]; 避免来自 `struct S as[] = NULL;` 的段错误;`? [复制]

Posted

技术标签:

【中文标题】使用 `struct S const char *array[ARG_MAX]; 避免来自 `struct S as[] = NULL;` 的段错误;`? [复制]【英文标题】:Avoid segfault from `struct S as[] = NULL;` with `struct S const char *array[ARG_MAX]; ;`? [duplicate]使用 `struct S const char *array[ARG_MAX]; 避免来自 `struct S as[] = NULL;` 的段错误;`? [复制] 【发布时间】:2021-10-19 20:27:39 【问题描述】:

在带有 gcc -ansi 的 Apple clang 版本 12.0.5 (clang-1205.0.22.11) 上,以下会产生段错误:

#include <stdlib.h>

#define ARG_MAX 1024 * 1024

struct S  const char *array[ARG_MAX]; ;

int main(void) 
    struct S as[] = NULL;
    return EXIT_SUCCESS;

ARG_MAXsys/syslimits.h 中定义为1024 * 1024,上面明确定义。

如何避免段错误?

【问题讨论】:

您正在溢出堆栈。如果你真的需要这么大的数组,用malloc创建它。 在堆上分配,而不是杀死栈? 有什么方法可以检查堆栈大小吗? - 同时我会#define ARG_MAX 131072 ulimit -a 检查堆栈大小限制。 【参考方案1】:

在大多数实现中应避免使用具有自动存储持续时间的大型数组(也称为局部变量),因为它们通常使用具有固定且相当有限大小的堆栈,例如在 1-8 MB 范围内。如果对象大小超过可用堆栈,则可能会发生各种事情。包括段错误。

如何避免段错误?

使用动态分配,例如:

#define ARG_MAX (1024 * 1024)

struct S  const char *array[ARG_MAX]; ;
int main(void) 
    struct S * as = calloc(1, sizeof *as);
    if (as == NULL) exit(EXIT_FAILURE);

    ... use as[0] ...

    free(as);
    return EXIT_SUCCESS;

大多数实现都有更多的内存可用于动态分配的对象。它通常称为堆内存。

顺便说一句:您的代码创建一个包含单个元素的数组是合法的,但有点奇怪。

【讨论】:

请注意,calloc() 提供的零初始化不一定等同于 OP 的初始化程序的效果,因为表示所有位为零的指针不一定是空指针。如果它是一个空指针,它不一定是通过初始化程序获得的 same 空指针值。可以有多个空指针表示,但它们必须相互比较。 我使用ARG_MAX 的原因是尽可能指定最长的CLI 参数;不使用动态分配。但在 macOS 上,整个 1024*1024 限制非常大。我应该在 macOS 上使用不同的 #define 吗? @SamuelMarks 我不清楚您要做什么。堆栈大小和程序参数数量无关

以上是关于使用 `struct S const char *array[ARG_MAX]; 避免来自 `struct S as[] = NULL;` 的段错误;`? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

请问C语言如何把2个const char * const s1的字符串合并?

c++ uint32 如何转 const char

const char * char const * char * const 三者的区别

const char * char const * char * const 三者的区别

不存在从 std 字符串到 const char * 的合适转换函数

如何在 const struct 中初始化联合?