【问题标题】:Very large struct and getting segmentation fault [duplicate]非常大的结构并出现分段错误[重复]
【发布时间】:2018-10-21 21:07:43
【问题描述】:

所以我试图声明一个大小为 19,000 的结构,但是当我编译它时,我得到 Seg 错误,核心转储。我想我必须使用 malloc 但我不能 考虑到我没有使用指针,找出最好的语法!

Struct people{
    char name[100]
    char secondname[100]
   }


int main(){
    struct people p1[19000]
}

以上是我的问题对应的代码

任何帮助将不胜感激

【问题讨论】:

  • 要么增加平台上的堆栈限制(即ulimit -s unlimited),要么使用struct people *p1 = malloc(19000*sizeof *p1); 在堆上分配。
  • 而且,仅供参考,术语 “我认为我必须使用 malloc”“我没有使用指针!!” 是一厢情愿想同时做。如果你做前者,你最好做后者。
  • 为了强调@WhozCraig 所说的,当您使用[ ] 表示法来访问您正在使用指针的数组时,您只是没有意识到这一点。
  • malloc 返回一个指针,所以无法避免它们;类似#include <stdlib.h> ... struct people *p1 = malloc(sizeof *p1 * 19000); if(!p1) perror("people"), exit(EXIT_FAILURE);
  • @ctx:从技术上讲,是的。数组在添加索引之前衰减到一个指针。 (E1[E2](*((E1)+(E2))) 相同——6.5.2.1/2。另见 6.5.2.1/1,约束。)

标签: c struct malloc


【解决方案1】:

您的struct 数组需要大约 3.8Mb 的堆栈空间,而在大多数现代桌面平台上,典型的默认进程或线程堆栈可能是几 Mb。

您可以动态或静态分配内存。静态分配如果最简单和合适的话就是数组的生命周期是程序执行的持续时间,并且所需的大小是已知的先验

int main()
{
    static struct people p1[19000] ;
}

动态分配是一种可能的解决方案,但是由于malloc() 返回一个指向已分配内存的指针,因此您必须使用指针;但是可以使用数组访问表示法,因此您的指针暴露将最小:

int main()
{
    struct people* p1 = malloc(sizeof(struct people) *19000 ) ;

    ...

    // Access to elements of the dynamically allocated array
    // is identical to that of the statically allocated array.
    printf( "%s", p1[0].name ) ;
}

动态分配的一个优点是您可以避免分配任意大的空间,并按需创建记录,将指针存储在动态调整大小的数组中(例如使用realloc()),或者一些合适的容器数据结构,例如链表。但也许这对你目前的情况来说太先进了。

【讨论】:

  • “static”关键字会自动在堆栈上创建更多内存吗?
  • 你如何计算 181Mb?我认为,它“只有” 19000*200 = 3800000 (3.8MB)
  • @anneb :不,它在单独的内存中分配它 - 它是永久的并且与堆栈分开,并且仅实例化和初始化一次 - 即使它具有本地范围。要增加堆栈大小,您需要查阅编译器和/或操作系统文档。例如:stackoverflow.com/questions/2275550/…
  • @Ctx :我无能计算181Mb!固定。
【解决方案2】:

struct people p1[19000] 尝试在自动堆栈内存中创建 19000 个 100+100 字节的结构。普通堆栈内存不够大,会出现堆栈溢出或其他错误。

在 C 中,可用的堆内存要多得多,但程序员必须进行堆内存管理

要在堆内存中分配数组,您可以使用例如:

int main() {
   struct people *p1 = malloc(19000 * sizeof(struct people));
   // you can now access p1 using array brackets as follows:
   // strcpy(p1[0].name, "name");
   // strcpy(p1[0].secondname, "secondname");
   // printf("name: %s, secondname: %s\n", p1[0].name, p1[0].secondname);

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 2021-11-08
    • 2014-01-24
    • 2014-05-31
    • 2011-03-23
    相关资源
    最近更新 更多