c - 为什么访问结构时会出现段错误?

标签 c data-structures struct header segmentation-fault

编辑:添加了我的其余代码,以便更容易查看

当我尝试访问头文件中结构的某些值时,收到段错误。

这是类(class).c:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "structs.h"

void createStudents () {
  int random, i;

  for (i = 0; i < 12; i++) {
    students[i].firstName = firstName[i];
    students[i].lastName = lastName[i];
    random = 10000 + rand() % 89999;
    students[i].num.studentNum = random;
    printf("%d - %s, %s \n", students[i].num.studentNum, students[i].lastName, students[i].firstName);
  }
}

void createCourses () {
  int numbers[999];
  int numbersLeft = 999;
  char courseCode[512];
  char courseCode1[512];
  char courseCode2[512];
  int numCourses = 3;
  int random, i, j;

  for (i = 0; i < 999; i++) {
    numbers[i] = i;
  }

  for (j = 0; j < 1; j++) {
    random = rand() % numbersLeft;
    if (random < 10) {
      snprintf(courseCode, sizeof courseCode, "CS00%d", random);
      courses[0].cCode = courseCode;
    }
    else if (random < 100 && random > 9) {
      snprintf(courseCode, sizeof courseCode, "CS0%d", random);
      courses[0].cCode = courseCode;
    }
    else if (random > 99){
      snprintf(courseCode, sizeof courseCode, "CS%d", random);
      courses[0].cCode = courseCode;
    }
    courses[0].cName = courseName[0];
    courses[0].cDescription = courseDescription[0];

    numbers[random] = numbers[numbersLeft-1];
    numbersLeft--;

    random = 4 + rand() % 4;
    courses[0].maxRegister = random;
  }

  for (j = 0; j < 1; j++) {
    random = rand() % numbersLeft;
    if (random < 10) {
      snprintf(courseCode1, sizeof courseCode1, "CS00%d", random);
      courses[1].cCode = courseCode1;
    }
    else if (random < 100 && random > 9) {
      snprintf(courseCode1, sizeof courseCode1, "CS0%d", random);
      courses[1].cCode = courseCode1;
    }
    else if (random > 99){
      snprintf(courseCode1, sizeof courseCode1, "CS%d", random);
      courses[1].cCode = courseCode1;
    }
    courses[1].cName = courseName[1];
    courses[1].cDescription = courseDescription[1];

    numbers[random] = numbers[numbersLeft-1];
    numbersLeft--;

    random = 4 + rand() % 4;
    courses[1].maxRegister = random;
  }
  for (j = 0; j < 1; j++) {
    random = rand() % numbersLeft;
    if (random < 10) {
      snprintf(courseCode2, sizeof courseCode2, "CS00%d", random);
      courses[2].cCode = courseCode2;
    }
    else if (random < 100 && random > 9) {
      snprintf(courseCode2, sizeof courseCode2, "CS0%d", random);
      courses[2].cCode = courseCode2;
    }
    else if (random > 99){
      snprintf(courseCode2, sizeof courseCode2, "CS%d", random);
      courses[2].cCode = courseCode2;
    }
    courses[2].cName = courseName[2];
    courses[2].cDescription = courseDescription[2];

    numbers[random] = numbers[numbersLeft-1];
    numbersLeft--;

    random = 4 + rand() % 4;
    courses[2].maxRegister = random;
  }
}

void regiserStudents () {
  int checkSum = 0, checkSum1 = 0, checkTemp = 0, count0 = 0, count1 = 0, count2 = 0;
  int wCount0 = 0, wCount1 = 0, wCount2 = 0;
  int v, i, j, random, max0, max1, max2;
  max0 = courses[0].maxRegister;
  max1 = courses[1].maxRegister;
  max2 = courses[2].maxRegister;

  for (i = 0; i < 2; i++) {
    checkTemp = count0;

    for (j = 0; j < 12; j++) {
      random = rand() % 3;
      if (random == 0) {
        if (count0 == 0) {
          courses[random].registered[count0] = &students[j];
          count0++;
        }
        else {
          checkSum1 = students[j].num.studentNum;

          for (v = 0; v < checkTemp; v++) {
            checkSum = courses[0].registered[v]->num.studentNum;
            if (checkSum == checkSum1) {
              /*Do Nothing*/
            }
            else if (count0 == max0) {
              courses[random].waitlisted[count0] = &students[j];
              wCount0++;
            }
            else {
              courses[random].registered[count0] = &students[j];
              count0++;
            }
          /*}*/
          }
        }
      }
      if (random == 1) {
        if (count1 == 0) {
          courses[random].registered[count1] = &students[j];
          count1++;
        }
        else {
          checkSum1 = students[j].num.studentNum;

          for (v = 0; v < checkTemp; v++) {
            checkSum = courses[1].registered[v]->num.studentNum;
            if (checkSum == checkSum1) {
              /*Do Nothing*/
            }
            else if (count1 == max1) {
              courses[random].waitlisted[count1] = &students[j];
              wCount1++;
            }
            else {
              courses[random].registered[count1] = &students[j];
              count1++;
            }
          }
        }
      }
      if (random == 2) {
        if (count2 == 0) {
          courses[random].registered[count2] = &students[j];
          count2++;
        }
        else {
          checkSum1 = students[j].num.studentNum;

          for (v = 0; v < checkTemp; v++) {
            checkSum = courses[2].registered[v]->num.studentNum;
            if (checkSum == checkSum1) {
              /*Do Nothing*/
            }
            else if (count2 == max2) {
              courses[random].waitlisted[count2] = &students[j];
              wCount2++;
            }
            else {
              courses[random].registered[count2] = &students[j];
              count2++;
            }
          }
        }
      }
    }
  }
  courses[0].studentRegistered = count0;
  courses[1].studentRegistered = count1;
  courses[2].studentRegistered = count2;

  courses[0].studentWaitlisted = wCount0;
  courses[1].studentWaitlisted = wCount1;
  courses[2].studentWaitlisted = wCount2;
}

void printCourses () {
  int i;
  printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[0].cCode, courses[0].cName, courses[0].cDescription, courses[0].studentRegistered, courses[0].maxRegister);

  for (i = 0; i < courses[0].studentRegistered; i++) {
    printf("* %d - %s, %s \n", courses[0].registered[i]->num.studentNum, courses[0].registered[i]->lastName, courses[0].registered[i]->firstName);
  }
  printf("Waitlisted Students (%d)", courses[0].studentWaitlisted);
  if (courses[0].studentWaitlisted == 0) {
    printf("\n");
  }
  else {
    for (i = 0; i < courses[0].studentWaitlisted; i++) {
      printf("* %d - %s, %s \n", courses[0].waitlisted[i]->num.studentNum, courses[0].waitlisted[i]->lastName, courses[0].waitlisted[i]->firstName);
    }
  }

  printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[1].cCode, courses[1].cName, courses[1].cDescription, courses[1].studentRegistered, courses[1].maxRegister);

  for (i = 0; i < courses[1].studentRegistered; i++) {
    printf("* %d - %s, %s \n", courses[1].registered[i]->num.studentNum, courses[1].registered[i]->lastName, courses[1].registered[i]->firstName);
  }
  printf("\n%s - %s: %s\nRegistered Students (%d/%d):\n", courses[2].cCode, courses[2].cName, courses[2].cDescription, courses[2].studentRegistered, courses[2].maxRegister);

  for (i = 0; i < courses[2].studentRegistered; i++) {
    printf("* %d - %s, %s \n", courses[2].registered[i]->num.studentNum, courses[2].registered[i]->lastName, courses[2].registered[i]->firstName);
  }
}

这是我的头文件

结构体.h

#ifndef STRUCTS_H_
#define STRUCTS_H_

char *firstName[] = {
  "Emma", "Liam", "Olivia",
  "Noah", "Ava", "Logan",
  "Sophia", "Lucas", "Isabella",
  "Mason", "Shaylyn", "Jack"
};

char *lastName[] = {
  "Smith", "Johnson", "Williams",
  "Brown", "Jones", "Miller",
  "Davis", "Garcia", "Rodriguez",
  "Wilson", "Seguin", "Loveday"
};

typedef struct{
  int studentNum;
}studentNumber;

typedef struct{
  char *firstName;
  char *lastName;
  studentNumber num;
}studentID;

studentID students[12];

char *courseName[] = {"Web Programming", "Technical Communication", "Processor Architecture"};
char *courseDescription[] = {"Learn the language of HTML, and how to create websites.", "Learn the essentials of communication skills, and how to apply them on the job.", "Learn the basics of circuits and Machine Language coding."};

typedef struct {
  int maxRegister;
  char *cCode;
  char *cName;
  char *cDescription;
  studentID *registered[8];
  studentID *waitlisted[12];
  int studentRegistered;
  int studentWaitlisted;
}course;

course courses[3];


#endif

打印注册学生的值工作正常,但当我打印候补学生时,出现段错误。我使用gdb,发现它在这一行,但不明白为什么:

printf("%d - %s, %s \n", courses[0].waitlisted[i]->num.studentNum, courses[0].waitlisted[i]->lastName, courses[0].waitlisted[i]->firstName);

最佳答案

studentID *waitlisted[12]; 这意味着它们将保存类型结构studentID的变量的地址。您只是没有这样做,而是开始访问这些指针变量。您已将它们传递给 scanf,由于尝试读取未初始化的指针变量,它会调用未定义的行为。

那么你需要在这里做什么 -

courses[i].waitlisted = malloc(sizeof *courses[i].waitlisted * courses[i].studentWaitlisted);

studentID 也是如此。这里的fistName是一个char*,你需要分配一些内存来访问它,否则它就是UB。

或者

typedef struct{
  char firstName[100]; //you are considering that name length would be 100
                       //at max.
  char lastName[100];
  studentNumber num;
}studentID;
<小时/>

OP编辑问题后:

您遇到的段错误是因为在局部变量的生命周期结束后访问它。

courses[0].cCode = courseCode;

你能做的是

courses[0].cCode = strdup(courseCode);

初始化数组intnumbers[999]={0};否则你可能会访问垃圾值,因为索引是随机数生成的结果。

if( random < 999){
    numbers[random] = numbers[numbersLeft-1];
    numbersLeft--;
}
else{
    fprintf(stderr, "%s\n","Error" );
}

大量重复代码。您应该删除重复的代码。而且也不需要single-iteration-for-loop

关于c - 为什么访问结构时会出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47585907/

相关文章:

arrays - 将数组值处理到结构数组的单个字段(在 Matlab 中)

c++ - C 和 C++ 中空结构的大小

java - 循环队列: array values disappears when doubling size

Java链表add方法

c++ - 什么是 C 中的通用库?

c - 声明结构数组

c - 在 C 中不使用任何数组符号来切换字符串

调用 1 个函数来生成 2 个不同的二维数组

c - 执行运行时期间的电平变化中断

c - 将 C 结构翻译为 Fortran 等价物