我正在做一些结构练习,无法理解分段错误。我几乎所有的事情都做得很好,(I=0;I<2;I++(的分段故障正在循环中
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<stdint.h>
#define MAX 50
int main(void)
{
typedef struct {
char *name;
char *l_name;
u_int32_t age;
}person;
u_int32_t i;
person p[2];
p->name = (char *) malloc(sizeof(char) * MAX);
p->l_name = (char *) malloc(sizeof(char)* MAX);
if(p->name == NULL || p->l_name == NULL){
fprintf(stderr,"Error allocating memory");
exit(1);
}
for(i = 0;i<2;i++){
if(!fgets(p[i].name,sizeof(p[i].name),stdin)){
fprintf(stderr,"Error reading string");
exit(2);
}
if(!fgets(p[i].l_name,sizeof(p[i].l_name),stdin)){
fprintf(stderr,"Error reading string");
exit(3);
}
}
}
您声明了一个由两个元素组成的数组
person p[2];
并且您只初始化了第一个元素p[0]
的数据成员
p->name = (char *) malloc(sizeof(char) * MAX);
p->l_name = (char *) malloc(sizeof(char)* MAX);
上述声明相当于
p[0].name = (char *) malloc(sizeof(char) * MAX);
p[0].l_name = (char *) malloc(sizeof(char)* MAX);
第二元素CCD_ 2的数据成员未被初始化并且具有不确定的值。
因此,当您试图使用数组第二个元素的这些未初始化的数据成员(例如(时,for循环会调用未定义的行为
if(!fgets(p[i].name,sizeof(p[i].name),stdin)){
此外,您在调用fgets
时使用了错误的表达式
sizeof(p[i].name)
数据成员name
(以及l_name
(是指针。因此,上面的表达式将产生一个指针的大小。
相反,您只需要编写MAX
,例如
if(!fgets(p[i].name, MAX, stdin )){
代码无法为所有p[i].name
进行分配。
传递给fgets()
的大小错误。
考虑在读取之后分配。读取到本地缓冲区,然后形成大小合适的副本。
for(i = 0; i<2; i++) {
char buf[MAX + 2];
if (fgets(buf, sizeof buf, stdin)) {
fprintf(stderr,"Error reading string");
exit(2);
}
buf[strcspn(buf, "n")] = 0; // Lop off potential n
p[i].name = strdup(buf); // Common, but non-standard string allocation
if (fgets(buf, sizeof buf, stdin)) {
fprintf(stderr,"Error reading string");
exit(3);
}
buf[strcspn(buf, "n")] = 0;
p[i].lname = strdup(buf);
}
如果您的库中没有strdup()
示例。