为什么在C程序中声明变量时会出现分段错误?

Ste*_*n N 1 c struct segmentation-fault

在我正在开发的C程序中出现分段错误后,我意识到错误来自我声明的变量.

这是我第一次尝试声明下面定义的数据类型Ens_participants的变量:

typedef struct 
{
    int cardinal;
    Participant tab[NB_MAX_PARTICIPANTS];
} Ens_participants;
Run Code Online (Sandbox Code Playgroud)

参与者是我在下面定义的另一种数据类型:

typedef struct 
{ 
    char nom[TMAX_MOT];
    char prenom[TMAX_MOT];
    char email[TMAX_MOT];
    char nationalite[TMAX_MOT];
    char langues_parles[LMAX][TMAX_MOT];
    char langues_cherches[LMAX][TMAX_MOT];
    int age;
    char sexe;
    char universite[TMAX_MOT];
    char disponible[TMAX_MOT];
} Participant; 
Run Code Online (Sandbox Code Playgroud)

使用TMAX_MOT,NB_MAX_PARTICIPANTS和LMAX是常量:

#define TMAX_MOT 250
#define LMAX 500

#define NB_MAX_PARTICIPANTS 1000
Run Code Online (Sandbox Code Playgroud)

这是导致我的分段错误的行:

Ens_participants les_participants; 
Run Code Online (Sandbox Code Playgroud)

我是否正确创建并声明了这些变量?单个声明如何导致分段错误?如果它有帮助,使用gdb调试器,我被告知在此声明之前错误来了两行:

int ligne_valide = 1;
Run Code Online (Sandbox Code Playgroud)

但是,这是错误的,因为该程序与上述方法配合良好.一旦我试图宣布这个新变量我就开始遇到问题了.

更新NO1

当我将常量NB_MAX_PARTICIPANTS的值更改为10而不是1000时,程序编译完美.

更新NO2

我为这个问题道歉,因为正如@alk所说,我的问题在于其他地方.我只重写了程序的类型并进行了实验.问题不在我想象的地方.变量定义和声明不会在新程序中引起任何问题.

Ste*_*ven 5

可能只是您的变量对于平台上可用的堆栈大小而言太大了.代码在技术上适用于C(因此,不是编译时错误),但实际上操作系统没有预留足够的堆栈空间来实现这一点.

毕竟,你的langues_parles字段自带250*500字节的空间; 即125kB.你有三个这样的字段,然后是其他一些字段,所以结构的每个实例大约需要380kB.

现在,您还没有显示NB_MAX_PARTICIPANTS的值,但我的猜测是380kB*NB_MAX_PARTICIPANTS太大了.例如,在Windows上,默认堆栈大小仅为1MB,因此如果NB_MAX_PARTICIPANTS大于2,则变量太大(并且假设堆栈上没有其他内容).

您必须使用malloc()或类似函数在堆上分配您的结构:

Ens_participants* les_participants = malloc(sizeof(Ens_participants));
/* ... */
free(les_participants);
Run Code Online (Sandbox Code Playgroud)

  • @StefanN:如果你不习惯指针,很难解释,但是你可以尝试在"指针"和"malloc"上寻找C教程; 类似于:https://www.codingunit.com/c-tutorial-the-functions-malloc-and-free.尤金有一个好点; 你分配一个非常非常大的,低效的结构,最终你还是会碰到堆上问题,以及(如果不是有1000人参加,那么2000或10000,或一旦你分配大量内存别的东西) - 但如果这是一个"学习"程序,您可能希望一次解决一个问题,这可能没问题. (2认同)
  • @StefanN之前进入编程应该了解不同的数据结构.数据结构不一定由存储器巨大单个连续块,这是很难分配,但往往从相互链接的数据的许多不同的块.见*链表*对于一个简单的例子. (2认同)