读取字符串时出现C程序段错误
C program segmentation fault when reading string
我的背景是 c#,我现在正在努力学习 C。
为此,我正在研究这个示例程序。
我想要做的是读取每个 属性 成员的用户输入,并在循环中为每个成员分配策略。我设法做到了这一点,但是当我试图将 Policy_Type
读入时,我 运行 变成了 Segmentation Fault
错误。我很难理解为什么。
#include<stdio.h>
#include<string.h>
enum PolicyType
{
Car = 1,
Health = 2,
Travel = 3,
Pet = 4
};
// Member structure
struct Member
{
int Member_ID;
char Name[20];
int Policy_Count;
// Policy structure
struct Policy
{
char Policy_ID[20];
int Member_ID;
char Policy_Type[20];
int Premium;
} policies[]; // each member could maintain 0 or many policies - nested structure
};
void mainMenu(){
printf("1. Add new member\n");
printf("2. Display all members\n");
printf("3. Search member by name\n");
printf("4. Calculate total premium\n");
printf("5. Exit\n");
printf("Enter your choice--- ");
};
struct Member collectNewMemberDetails(){
struct Member member;
printf("a. Enter the member details:\n");
printf("b. Member Name:\n");
scanf("%s", member.Name); // saves the member name in structure
printf("c. Member ID:\n");
scanf("%d", &member.Member_ID);
printf("d. How many policies for the member:\n");
scanf("%d", &member.Policy_Count);
for (int i = 0; i < member.Policy_Count; i++)
{
char policyId[20];
char policyType[20];
int policyPremium;
printf("a. Enter Policy ID: \n");
scanf("%s", policyId);
printf("b. Enter Policy Type: \n");
scanf("%s", policyType);
printf("c. Enter Policy Premium: \n");
scanf("%d", &policyPremium);
strcpy(member.policies[i].Policy_ID, policyId );
strcpy(member.policies[i].Policy_Type, policyType );
member.policies[i].Premium = policyPremium;
member.policies[i].Member_ID = member.Member_ID;
}
return member;
}
int main(int argc, char const *argv[])
{
mainMenu();
int choice;
scanf("%d", &choice);
struct Member newMember;
switch (choice)
{
case 1:
newMember = collectNewMemberDetails();
break;
default:
break;
}
printf("Member name: %s\n", newMember.Name);
printf("Member Policy Type: %s\n", newMember.policies[0].Policy_Type);
return 0;
}
在与 dbg 的调试会话期间,在我输入 premium 后,我收到此错误:
-- omitted for brevity
c. Enter Policy Premium:
22
Thread 1 received signal SIGSEGV, Segmentation fault.
0x0000002b in ?? ()
我快要疯了,想知道为什么。
你能给我指明正确的方向吗?
非常感谢。
当一个结构体成员是一个没有指定大小的数组时,它被称为灵活的数组成员。为了使用该成员,您必须分配一些与您需要的数组大小相匹配的内存。因此,您需要使用指向 struct Member
而不是 struct Member
对象的指针。
当你做的时候
struct Member member;
没有为数组分配内存,即访问member.policies
是非法的。
而是使用指针和动态内存分配来为数组获取内存——例如:
struct Member* member;
size_t array_size = INPUT_THE_NUMBER_OF_POLICIES();
member = malloc(sizeof *member + array_size * sizeof(struct Policy));
\------------/ \--------------------------------/
Memory for Memory for the policies-array
first three
struct members
作为替代方案,您可以放弃使用灵活的数组并简单地使用指针 - 如:
struct Member
{
int Member_ID;
char Name[20];
int Policy_Count;
struct Policy * policies;
};
并喜欢:
struct Member collectNewMemberDetails(){
struct Member member;
...
printf("d. How many policies for the member:\n");
if (scanf("%d", &member.Policy_Count) != 1) exit(1);
assert(Policy_Count > 0);
member.policies = malloc(member.Policy_Count * sizeof *member.policies);
...
在C语言中,静态定义结构时必须指定结构的个数。如果你不知道一个用户有多少条策略,你必须指定策略结构的数量,最多你认为是最大的,或者你可以采用链表(在这种情况下,你必须在需要时分配使用策略结构)。
对于任何感兴趣的人,这就是我如何让它工作的:
// Policy structure
struct Policy
{
char Policy_ID[20]; // the policy id
int Member_ID; // owner member id of this policy
char Policy_Type[20]; // array to hold policy type.
int Premium; // premium amount
};
// Member structure
struct Member
{
int Member_ID; // member id
char Name[20]; // member name
int Policy_Count; // how many number of policies this member own
struct Policy * policies; // each member could maintain 0 or many policies - nested structure
};
我没有使用嵌套策略,而是将其移出。
并像这样构建成员:
struct Member collectNewMemberDetails(){
struct Member member;
printf("b. Member Name:\n");
scanf("%s", member.Name); // saves the member name in structure
printf("d. How many policies for the member:\n");
scanf("%d", &member.Policy_Count);
// without doing this gave me error Segmentation Fault.
// after googling I found out i need to allocate memory for my array
member.policies = malloc(member.Policy_Count * sizeof *member.policies);
for (int i = 0; i < member.Policy_Count; i++)
{
// create a new policy
struct Policy membePolicy;
membePolicy.Member_ID = member.Member_ID; // attach the member id to this policy
printf("a. Enter Policy ID: \n");
scanf("%s", &membePolicy.Policy_ID); // set the policy id
printf("b. Enter Policy Type: \n");
scanf("%s", &membePolicy.Policy_Type); // set the policy type
printf("c. Enter Policy Premium: \n");
scanf("%d", &membePolicy.Premium); // set the premium of this policy
member.policies[i] = membePolicy; // set the policy to member
}
return member;
}
然后成功了。
> .\policy.exe
1. Add new member
2. Display all members
3. Search member by name
4. Calculate total premium
5. Exit
Enter your choice--- 1
a. Enter the member details:
b. Member Name:
romesh
c. Member ID:
111
d. How many policies for the member:
1
a. Enter Policy ID:
1
b. Enter Policy Type:
Car
c. Enter Policy Premium:
233
Member name: romesh
Member Policy Type: Car
我的背景是 c#,我现在正在努力学习 C。
为此,我正在研究这个示例程序。
我想要做的是读取每个 属性 成员的用户输入,并在循环中为每个成员分配策略。我设法做到了这一点,但是当我试图将 Policy_Type
读入时,我 运行 变成了 Segmentation Fault
错误。我很难理解为什么。
#include<stdio.h>
#include<string.h>
enum PolicyType
{
Car = 1,
Health = 2,
Travel = 3,
Pet = 4
};
// Member structure
struct Member
{
int Member_ID;
char Name[20];
int Policy_Count;
// Policy structure
struct Policy
{
char Policy_ID[20];
int Member_ID;
char Policy_Type[20];
int Premium;
} policies[]; // each member could maintain 0 or many policies - nested structure
};
void mainMenu(){
printf("1. Add new member\n");
printf("2. Display all members\n");
printf("3. Search member by name\n");
printf("4. Calculate total premium\n");
printf("5. Exit\n");
printf("Enter your choice--- ");
};
struct Member collectNewMemberDetails(){
struct Member member;
printf("a. Enter the member details:\n");
printf("b. Member Name:\n");
scanf("%s", member.Name); // saves the member name in structure
printf("c. Member ID:\n");
scanf("%d", &member.Member_ID);
printf("d. How many policies for the member:\n");
scanf("%d", &member.Policy_Count);
for (int i = 0; i < member.Policy_Count; i++)
{
char policyId[20];
char policyType[20];
int policyPremium;
printf("a. Enter Policy ID: \n");
scanf("%s", policyId);
printf("b. Enter Policy Type: \n");
scanf("%s", policyType);
printf("c. Enter Policy Premium: \n");
scanf("%d", &policyPremium);
strcpy(member.policies[i].Policy_ID, policyId );
strcpy(member.policies[i].Policy_Type, policyType );
member.policies[i].Premium = policyPremium;
member.policies[i].Member_ID = member.Member_ID;
}
return member;
}
int main(int argc, char const *argv[])
{
mainMenu();
int choice;
scanf("%d", &choice);
struct Member newMember;
switch (choice)
{
case 1:
newMember = collectNewMemberDetails();
break;
default:
break;
}
printf("Member name: %s\n", newMember.Name);
printf("Member Policy Type: %s\n", newMember.policies[0].Policy_Type);
return 0;
}
在与 dbg 的调试会话期间,在我输入 premium 后,我收到此错误:
-- omitted for brevity
c. Enter Policy Premium:
22
Thread 1 received signal SIGSEGV, Segmentation fault.
0x0000002b in ?? ()
我快要疯了,想知道为什么。 你能给我指明正确的方向吗?
非常感谢。
当一个结构体成员是一个没有指定大小的数组时,它被称为灵活的数组成员。为了使用该成员,您必须分配一些与您需要的数组大小相匹配的内存。因此,您需要使用指向 struct Member
而不是 struct Member
对象的指针。
当你做的时候
struct Member member;
没有为数组分配内存,即访问member.policies
是非法的。
而是使用指针和动态内存分配来为数组获取内存——例如:
struct Member* member;
size_t array_size = INPUT_THE_NUMBER_OF_POLICIES();
member = malloc(sizeof *member + array_size * sizeof(struct Policy));
\------------/ \--------------------------------/
Memory for Memory for the policies-array
first three
struct members
作为替代方案,您可以放弃使用灵活的数组并简单地使用指针 - 如:
struct Member
{
int Member_ID;
char Name[20];
int Policy_Count;
struct Policy * policies;
};
并喜欢:
struct Member collectNewMemberDetails(){
struct Member member;
...
printf("d. How many policies for the member:\n");
if (scanf("%d", &member.Policy_Count) != 1) exit(1);
assert(Policy_Count > 0);
member.policies = malloc(member.Policy_Count * sizeof *member.policies);
...
在C语言中,静态定义结构时必须指定结构的个数。如果你不知道一个用户有多少条策略,你必须指定策略结构的数量,最多你认为是最大的,或者你可以采用链表(在这种情况下,你必须在需要时分配使用策略结构)。
对于任何感兴趣的人,这就是我如何让它工作的:
// Policy structure
struct Policy
{
char Policy_ID[20]; // the policy id
int Member_ID; // owner member id of this policy
char Policy_Type[20]; // array to hold policy type.
int Premium; // premium amount
};
// Member structure
struct Member
{
int Member_ID; // member id
char Name[20]; // member name
int Policy_Count; // how many number of policies this member own
struct Policy * policies; // each member could maintain 0 or many policies - nested structure
};
我没有使用嵌套策略,而是将其移出。
并像这样构建成员:
struct Member collectNewMemberDetails(){
struct Member member;
printf("b. Member Name:\n");
scanf("%s", member.Name); // saves the member name in structure
printf("d. How many policies for the member:\n");
scanf("%d", &member.Policy_Count);
// without doing this gave me error Segmentation Fault.
// after googling I found out i need to allocate memory for my array
member.policies = malloc(member.Policy_Count * sizeof *member.policies);
for (int i = 0; i < member.Policy_Count; i++)
{
// create a new policy
struct Policy membePolicy;
membePolicy.Member_ID = member.Member_ID; // attach the member id to this policy
printf("a. Enter Policy ID: \n");
scanf("%s", &membePolicy.Policy_ID); // set the policy id
printf("b. Enter Policy Type: \n");
scanf("%s", &membePolicy.Policy_Type); // set the policy type
printf("c. Enter Policy Premium: \n");
scanf("%d", &membePolicy.Premium); // set the premium of this policy
member.policies[i] = membePolicy; // set the policy to member
}
return member;
}
然后成功了。
> .\policy.exe
1. Add new member
2. Display all members
3. Search member by name
4. Calculate total premium
5. Exit
Enter your choice--- 1
a. Enter the member details:
b. Member Name:
romesh
c. Member ID:
111
d. How many policies for the member:
1
a. Enter Policy ID:
1
b. Enter Policy Type:
Car
c. Enter Policy Premium:
233
Member name: romesh
Member Policy Type: Car