【问题标题】:Using switch/case with malloc()在 malloc() 中使用 switch/case
【发布时间】:2018-12-11 21:06:06
【问题描述】:

我正在尝试编写代码以将患者添加到列表中。这是一个很大的代码,但我在输入患者姓名的特定部分遇到问题。我可以正确输入名称,但是当我尝试将代码放入开关/机箱时,它停止正常工作。我想知道这里是否有人可以提供帮助。

最初我认为可能是 malloc 导致了问题,但如果没有 switch/case,它似乎可以正常工作。

代码:

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

typedef unsigned long int u32;
typedef unsigned char u8;
typedef struct Patient patient;
struct Patient
{
    u8* name;
    patient* next;
};

void addfirstpatient(u8* name);
void addpatient(u8* name);
void print (void);
patient* head;
u8 length = 0;

int main()
{
    u32 x = 1;

    switch(x)
    {
        u8* name = malloc(20*sizeof(u8));
        case 1:
        printf("\nPlease enter patient name:");
        scanf("%s",name);
        if(length == 0)
        {
            addfirstpatient(name);
        }
        else
        {
            addpatient(name);
        }
        print();
        printf("\nPatient added , Thank you\n");
        printf("\nTo add another patient press 1");
        scanf("%d",&x);
        break;

        case 2:
        break;

        default:
        printf("\nentered default");
    }

return 0;
}

void addfirstpatient(u8* name)
{
    printf("\nadding first patient: ");
    head = (patient*)malloc(sizeof(patient));
    head->next = NULL;
    head->name = name;

    length++;
}

void addpatient(u8* name)
{
    patient* ptr = head;
    while((ptr->next)!=NULL)
    {
        ptr = ptr->next;
    }
    printf("\nadding patient");
     ptr->next = (patient*)malloc(sizeof(patient));
    (ptr->next)->next = NULL;
    (ptr->next)->name = name;
    length++;
}

void print (void)
{
    patient *ptr = head;
    u32 count = 1;
    printf("\n---------------------");
    if (ptr == NULL)
    {
        printf ("\nList is empty");
    }
    while (ptr!=NULL)
    {
        printf("\npatient Number %d\nname:%s" ,count,ptr->name);
        ptr = ptr->next;
        count++;
    }
    printf("\n---------------------");
    printf("\n");
}

【问题讨论】:

  • 打开编译器警告并将其视为错误。应该告诉您,没有 case 标签的 malloc 行将永远不会执行。
  • 什么意思,它停止工作了?您是否收到编译器错误?运行时错误?崩溃?请将任何此类消息剪切并粘贴到问题中
  • 请注意,scanf("%s",name); 是一个等待吞噬第一个输入超过 19 个字符的人的黑洞。 scanf("%19s",name); 会更安全。

标签: c string switch-statement malloc


【解决方案1】:
   switch(x)
    {
        u8* name = malloc(20*sizeof(u8));
        case 1:

不合法 - 很惊讶它编译(也许它不,也许那是你的错误)。你需要

   u8* name = malloc(20*sizeof(u8));
   switch(x)
    {
        case 1:

或许

 u8* name = NULL;
   switch(x)
    {
        case 1:
           name = malloc(20*sizeof(u8));

取决于您希望何时分配该数组

当然你应该检查 malloc 的返回。

【讨论】:

  • 不应该真的在case 1:里面,以免造成内存泄漏吗?
  • 只有在 x = 1 时才会发生这种情况。但是原始代码的设置方式似乎应该在每种情况下都会发生。
  • 可能不是非法的,但它永远不会执行,所以编译器应该将其标记为无法访问的代码
  • 你不能在标签后面加上声明。 GCC 投诉:error: a label can only be part of a statement and a declaration is not a statement.
【解决方案2】:

虽然像你这样的结构......

   switch(x)
    {
        u8* name = malloc(20*sizeof(u8));
        case 1:

... 在技术上是合法的,它不能达到你想要的。它确实声明了变量name,然后它在switch的整个主体范围内,但如果它完全进入主体,执行总是跳到casedefault标签,因此初始化程序(包含 malloc() 调用)永远不会被评估,也不会为变量 name 分配初始值。

您应该如何实际进行取决于您想要完成的任务。如果您只希望变量name 在一个case 中,那么在此处声明和初始化它可能更有意义,但您不能在标签之后立即这样做。但是,您可以将其包含在自己的块中,也可以在其之间放置一个可执行语句:

   switch(x) {
       case 1: {
           u8* name = malloc(20*sizeof(u8));
           // ...
       }
       // ...

如果您希望它用于多个cases,那么最好在switch之外声明它:

   u8* name = malloc(20*sizeof(u8));
   switch(x) {
       case 1:
       // ...

如果你将声明留在原处,那么在使用它之前必须小心地为其分配一个值,适当的case标签之后:

   switch(x) {
       u8* name;
       case 1:
       name = malloc(20*sizeof(u8));
       // ...

但是,我敦促您不要选择这种方法,因为它的风格很差。

【讨论】:

  • 你不能在标签后面加上声明。 GCC 投诉:error: a label can only be part of a statement and a declaration is not a statement.
  • 是的,@JonathanLeffler。已更正,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多