gpt4 book ai didi

c - 在 C 中使用结构的段错误

转载 作者:太空宇宙 更新时间:2023-11-04 01:45:48 26 4
gpt4 key购买 nike

我正在通过编写一个小型 C 程序来测试我们最近在类里面学到的有关结构和指针的内容。然而,在运行它之后我遇到了一个segmentation fault (core dumped) 错误。有人可以帮我弄清楚到底是哪里造成的吗?我是不是遗漏了任何悬挂指针,还是我使用 malloc() 做错了什么?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char *admin = "Administrator";
const char *mng = "Manager";
const char *prog = "Programmer";

struct employee {
char *name;
char title[20];
char id[8];
int yearsExp;
};

typedef struct employee emp_t;

emp_t *everyone[1];

emp_t *create_emp(const char *name,const char *title,const char *id,int yrxp) {
emp_t *new;

new = (emp_t *) malloc(sizeof(emp_t));
new->name = (char*) malloc(strlen(name) + 1);
strcpy(new->name,name);
strcpy(new->title,title);
strcpy(new->id,id);
new->yearsExp = yrxp;
return new;
}

void free_emp(emp_t *employee) {
free(employee->name);
free(employee);
}

int main() {
int i;

everyone[0] = create_emp("Mike Papamichail",prog,"A197482",3);
everyone[1] = create_emp("Maria Mamalaki",mng,"Z104781",6);

for(i = 0; i < 2;i++) {
printf("%15s \t %15s \t %10s \t %4d\n",
everyone[0]->name,everyone[0]->title,everyone[0]->id,everyone[0]->yearsExp);
free_emp(everyone[i]);
everyone[i] = NULL;
}
return 0;
}

为了清晰起见更新了代码

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char *admin = "Administrator";
const char *mng = "Manager";
const char *prog = "Programmer";

struct employee {
char *name;
char title[20];
char id[8];
int yearsExp;
};

typedef struct employee emp_t;

emp_t *create_emp(const char *name,const char *title,const char *id,int yrxp) {
emp_t *new;

new = (emp_t *) malloc(sizeof(emp_t));
new->name = (char*) malloc(strlen(name) + 1);
strcpy(new->name,name);
strcpy(new->title,title);
strcpy(new->id,id);
new->yearsExp = yrxp;
return new;
}

void free_emp(emp_t *employee) {
free(employee->name);
free(employee);
}

int main() {
int i;
emp_t *everyone[2];

everyone[0] = create_emp("Mike Papamichail",prog,"A197482",3);
everyone[1] = create_emp("Maria Mamalaki",mng,"Z104781",6);

for(i = 0; i < 2;i++) {
printf("%15s \t %15s \t %10s \t %4d\n",
everyone[0]->name,everyone[0]->title,everyone[0]->id,everyone[0]->yearsExp);
free_emp(everyone[i]);
everyone[i] = NULL;
}
return 0;
}

最佳答案

您在所有方面都很接近 @tadman在使用 emp_t *everyone[1] 创建 1 指针数组时遇到了最大的错误(现在已在您的问题中删除)。

相对而言,您的代码的其余问题更多是一些小的更正或改进。

对于初学者,请避免在您的代码中使用“魔数(Magic Number)”(例如20, 8, 2)。如果您需要常量,#define 它们,或使用全局 enum 一次定义多个常量,例如

/* an enum can be used to #define multiple constants */
enum { MAXID = 8, MAXTITLE = 20, MAXEMP = 128 };

然后

typedef struct {    
char *name;
char title[MAXTITLE]; /* avoid "magic-numbers", use constants */
char id[MAXID];
int yearsExp;
} emp_t;

您的 create_emp() 函数将大部分按原样运行,但无需强制转换 malloc、callocrealloc 的返回值在 C 中,请参阅:Do I cast the result of malloc? .此外,我会避免使用 new 作为临时结构名称。虽然在 C 中没有实际冲突,但 new 是 C++ 中的一个关键字,如果您将在两者中编写代码,最好记住这一点。通过一些调整,您可以编写如下 create_emp():

emp_t *create_emp (const char *name, const char *title, 
const char *id, int yrxp) {
emp_t *newemp; /* new is a keyword in C++ best to avoid */

newemp = malloc (sizeof *newemp); /* don't cast return of malloc */
/* if you allocate, you must validate */
if (newemp == NULL) {
perror ("malloc-newemp");
return NULL;
}
newemp->name = malloc (strlen(name) + 1);
if (newemp->name == NULL) {
perror ("malloc-newemp->name");
free (newemp);
return NULL;
}
strcpy (newemp->name, name);
strcpy (newemp->title, title);
strcpy (newemp->id, id);
newemp->yearsExp = yrxp;

return newemp;
}

(注意:始终验证每个分配。malloc、calloc 和 realloc 可能并且确实会失败)

最后,在 main() 中,您可以使用索引(下面的 ndx)代替 magic-number 2 并在每次添加时增加索引。虽然您可以很好地使用 field-width 修饰符来控制输出字段大小,但对于字符串(和所有转换说明符),您可以包括 '-' 标志作为一部分转换说明符以使字段左对齐 正确对齐输出。您的代码的其余部分没问题。

总而言之,您可以执行以下操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* an enum can be used to #define multiple constants */
enum { MAXID = 8, MAXTITLE = 20, MAXEMP = 128 };
#define ADMIN "Administrator" /* simple #defines are fine */
#define MNG "Manager" /* string literals are fine as well */
#define PROG "Programmer" /* (up to you) */

typedef struct {
char *name;
char title[MAXTITLE]; /* avoid "magic-numbers", use constants */
char id[MAXID];
int yearsExp;
} emp_t;

emp_t *create_emp (const char *name, const char *title,
const char *id, int yrxp) {
emp_t *newemp; /* new is a keyword in C++ best to avoid */

newemp = malloc (sizeof *newemp); /* don't cast return of malloc */
/* if you allocate, you must validate */
if (newemp == NULL) {
perror ("malloc-newemp");
return NULL;
}
newemp->name = malloc (strlen(name) + 1);
if (newemp->name == NULL) {
perror ("malloc-newemp->name");
free (newemp);
return NULL;
}
strcpy (newemp->name, name);
strcpy (newemp->title, title);
strcpy (newemp->id, id);
newemp->yearsExp = yrxp;

return newemp;
}

void free_emp (emp_t *employee) {
free (employee->name);
free (employee);
}

int main (void) {

int i, ndx = 0; /* use an index instead of magic-numbers */

emp_t *everyone[MAXEMP] = {NULL};

everyone[ndx++] = create_emp ("Mike Papamichail", PROG, "A197482", 3);
everyone[ndx++] = create_emp ("Maria Mamalaki", MNG, "Z104781", 6);
everyone[ndx++] = create_emp ("Sam Sunami", ADMIN, "B426310", 10);

for (i = 0; i < ndx; i++) { /* %- to left justify fields */
if (everyone[i]) { /* validate not NULL */
printf ("%-15s \t %-15s \t %-10s \t %4d\n", everyone[i]->name,
everyone[i]->title, everyone[i]->id,
everyone[i]->yearsExp);
free_emp (everyone[i]);
everyone[i] = NULL;
}
}

return 0;
}

(注意everyone[0]->nameeveryone[i]->name 的变化,等等,否则输出永远不会改变)

示例使用/输出

$ ./bin/emp_struct
Mike Papamichail Programmer A197482 3
Maria Mamalaki Manager Z104781 6
Sam Sunami Administrator B426310 10

检查一下,如果您还有其他问题,请告诉我。

关于c - 在 C 中使用结构的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53965129/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com