使用未初始化的内存”“警告

使用未初始化的内存

//职工信息
typedef struct work
{
    int id;            //工号
    char name[8];      //姓名
    int wages;         //工资
    int bonus;         //奖金
    int deduction;     //扣款
    int money;         //实发工资
    struct work* next; //链表
}workers; //别名

//表头
workers* Listhead()
{
    workers* head = (workers*)malloc(sizeof(workers));//动态内存申请 指针变成变量
    if (head != NULL)//消除vs警告
    {
        head->next = NULL;//初始化
        return head;      //返回头指针
    }
    return 0;
}

//删除
void del(workers* head)
{
    workers* p = head;
    int a = determine(p);
    if (a == 1)
        return;
    printf("工号:");
    int id;
    scanf_s("%d", &id);
    while (p->next!= NULL)
    {
        p = p->next;
        if (id == p->id)
        {
            printf("信息如下\n");
            format;
            printf("%-8d\t%-8s\t%-8d\t%-8d\t%-8d\n",
                p->id, p->name, p->wages, p->bonus, p->deduction);
            printf("是否要进行删除\n");
            printf("1——是\t2——否\n");
            int sel;
            scanf_s("%d", &sel);
            if (sel == 1)
            {
                workers* b = head;
                while (b->next != p)
                    b = b->next;
                b->next = p->next;
                free(p);
                printf("删除成功,是否保存\n");
                printf("1——是\t2——否\n");
                int a;
                scanf_s("%d", &a);
                if (a == 1)
                {
                    save(head);
                    printf("保存成功\n");
                    system("pause");
                    system("cls");
                    return;
                }
                else if (a == 2)
                {
                    system("pause");
                    system("cls");
                    return;
                }
            }
            else if (sel == 2)
            {
                system("pause");
                system("cls");
                return;
            }
        }
    }
    printf("未有此人\n");
    system("pause");
    system("cls");
}

int main()
{
    workers* head = NULL;
    head = Listhead();
    read(head);
    while (1)
    {
        int select = meun();
        switch (select)
        {
        case 1:
            scanfs(head);
            break;
        case 2:
            save(head);
            break;
        case 3:
            printfs(head);
            break;
        case 4:
            count(head);
            break;
        case 5:
            query(head);
            break;
        case 6:
            sort(head);
            break;
        case 7:
            modify(head);
            break;
        case 8:
            del(head);
            break;
        case 0:
            printf("已退出");
            return;
            break;
        default:
            break;
        }
    }
}

怎么消除这两个警告呀,一开始是没有的,莫名其妙的就出现了。而且我在main函数里是已经初始化了

img


邦邦!

这个警告不用管的,因为你定义的指针已经在p定义的时候已经指定了*p=head;
如果硬要修改可以修改为如下操作,看还报警不。

workers *p=NULL;
p=head;

函数开头,在worker *p = head后,加上p->next = NULL;

第435行:int a = determine(p); 这个 determine(p) 函数是啥作用?

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7698317
  • 这篇博客也不错, 你可以看下写一函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。
  • 除此之外, 这篇博客: 函数的调用过程,栈桢的创建和销毁中的 我们都知道局部变量存放在我们的栈区,所以我们把现在开辟的main函数的空间叫main函数的栈桢。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:





    紧接着我们在接着往下看汇编代码:

    	ret = Add(a, b);
    011B1443 8B 45 EC             mov         eax,dword ptr [ebp-14h]  
    //把ebp-14h(b)的值放到eax里,esp指向栈顶;
    011B1446 50                   push        eax  
    //把eax压到栈顶
    011B1447 8B 4D F8             mov         ecx,dword ptr [ebp-8]  
    //把ebp-8(a)的值放到eax里;esp指向栈顶;
    011B144A 51 push ecx
    //把ecx压到栈顶;
    011B144B E8 91 FC FF FF       call        _Add (011B10E1h)
    //call指令,调用函数;这个地方是最关键的地方
    //在这里我们按F11进入函数会跳转到如下这样一条语句:011B10E1 E9 DA 02 00 00       jmp         Add (011B13C0h);
    //我们还会发现内存里在2的上面又压进去一个地址,这个地址就是我们下面这一行汇编代码开头的地址(函数调用完返回值就要使用这个地址)。如下图所示。
    011B1450 83 C4 08             add         esp,8
    //效果如图所示:









    然后我们F11进入Add函数:

    011B13C0 55                   push        ebp  
    //这里压进去的其实是main函数的edp
    011B13C1 8B EC                mov         ebp,esp  
    011B13C3 81 EC CC 00 00 00    sub         esp,0CCh  
    011B13C9 53                   push        ebx  
    011B13CA 56                   push        esi  
    011B13CB 57                   push        edi  
    011B13CC 8D BD 34 FF FF FF    lea         edi,[ebp-0CCh]  
    011B13D2 B9 33 00 00 00       mov         ecx,33h  
    011B13D7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
    011B13DC F3 AB                rep stos    dword ptr es:[edi] 



    这里的汇编代码和之前的基本上道理是一致的,执行完效果图如下所示:






    int sum = 0;
    011B13DE C7 45 F8 00 00 00 00 mov         dword ptr [sum],0   
    sum = x + y;
    011B13E5 8B 45 08             mov         eax,dword ptr [ebp+8] 
    //ebp+8,此时ebp+8指向形参a;
    011B13E8 03 45 0C             add         eax,dword ptr [ebp+0Ch]  
    //ebp+0ch,指向形参b,把a+b放到eax里
    011B13EB 89 45 F8             mov         dword ptr [ebp-8],eax  
    //ebp-8就是sum所在的位置,把eax(a+b)的值给sum,sum=5;
    return sum;
    011B13EE 8B 45 F8             mov         eax,dword ptr [ebp-8] 
    //把sum的值再放到eax里,那么eax里存放的就是我们的返回值


    效果图如下所示:





    011B13F1 5F                   pop         edi  
    011B13F2 5E                   pop         esi  
    011B13F3 5B                   pop         ebx 
    //pop就是出栈的意思,esp此时指向ebx下面的空间,这三个地址相当于被回收了
    011B13F4 8B E5                mov         esp,ebp  
    //把ebp的值给esp
    011B13F6 5D                   pop         ebp
    //ebp就是我们所存储的main函数的ebp,那么此时ebp指向main函数里面的ebp
    011B13F7 C3                   ret  
    //ret指令要返回值,首先把栈顶call执行下一条指令的地址出栈,然后紧接着跳到下面这一行的地址,
    这也是之前为什么要把这个地址保存,就起到了一个返回值的作用
    //011B1450 83 C4 08             add         esp,8
    011B1450 83 C4 08             add         esp,8 
    //esp+8直接把定义的形参跳过去,到这一步的时候,我们就是Add的栈桢已经!!!被销毁了!!! 
    011B1453 89 45 E0 mov dword ptr [ebp-20h],eax
    //eax里存放的是Add函数里sum的值,把eax的值给ebp-20h(ret)就把sum的值返回了


    到这里函数的调用过程就结束了!!!

    最终效果图如下所示:


    到这里,函数的调用过程以及栈桢的创建、销毁就讲述完了!!!



    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^