代码之家  ›  专栏  ›  技术社区  ›  ScottishTapWater

由尚未运行的函数引起的错误

  •  2
  • ScottishTapWater  · 技术社区  · 6 年前

    所以我在写一个账单处理系统。数据当前位于 Stack 我写的结构。

    我有一个部分编写的函数,用于编写报告:

    void GenerateReport(Bill* bill)
    {
         PrintBillHeading(bill);
         //CallEntry* collatedEntries = CollapseCallStack(bill->callEntries);
    //TODO
    }
    

    只要我把第二行注释掉就行了。如果我取消注释它,我会在 PrintBillHeading()

    void PrintBillHeading(Bill* bill)
    {
        printf("Big Brother Telecom\n");
        printf("Bill Date: %s\n\n",DateTimeToISOString(bill->date));
        printf("Contract Holder: %s %s\n", bill->title, bill->name);
        printf("Address:\n");
        char* addressSeg;
        char* addressCpy;
        strcpy(addressCpy,bill->address); //This line throws the SIGSEGV
        while ((addressSeg = strtok_r(addressCpy,";",&addressCpy)))
        {
            printf("%s\n\0",addressSeg);
        }
    }
    

    CollapseCallStack() 函数,这是不完整的,完全未经测试,可能不起作用。

    CallEntry* CollapseCallStack(Stack* calls)
    {
        int size = calls->topIndex;
        CallEntry* collatedSet = malloc(sizeof(CallEntry) * size);
        CallEntry* poppedCall;
        int curIndex = 0;
        while (PopStack(calls,poppedCall))
        {
            bool found = false;
            for (int i = 0; i < size; i++)
            {
                CallEntry* arrItem = collatedSet + i * sizeof(CallEntry);
                if (StringEquals(arrItem->phoneNumber,poppedCall->phoneNumber))
                {
                    found = true;
                    arrItem->minutes += poppedCall->minutes;
                }
            }
            if (!found)
            {
                memcpy(collatedSet,poppedCall,sizeof(CallEntry)); //
            }
        }
    }
    

    CallEntry 结构:

    typedef struct{
        char* phoneNumber;
        int minutes;
        DateTime* callDateTime;
    } CallEntry;
    

    我的问题是:一个还没有被调用的函数怎么会导致一个SIGSEGV错误在程序的前面被表达?

    一旦我通过了这个,我就可以调试 CollapseCallStack() 尽管如果有人看到任何明显的问题,我希望能就此发表评论。

    2 回复  |  直到 6 年前
        1
  •  6
  •   AlexP    6 年前

    在功能上 PrintBillHeading() ,声明 strcpy(addressCpy,bill->address) 使用未初始化变量的值 addressCpy . 这是未定义的行为。未定义的行为意味着程序可能在任意位置崩溃。如果程序包含未定义的行为 整个程序无效 .

        2
  •  1
  •   Community CDub    5 年前

    除了 correct answer 通过AlexP,我想指出另一种(潜伏的)未定义的行为:

    void GenerateReport(Bill* bill)
    {
         PrintBillHeading(bill);
         CallEntry* collatedEntries = CollapseCallStack(bill->callEntries);
    //TODO
    }
    

    现在 CollapseCallStack 不归还任何东西 . 它仍然会被调用,实际上会为您的 collatedEntries 初始化它时的指针。

    问题是什么时候 衣领袋 调用时,将为返回值分配内存,但从未为其分配有意义的值,因为缺少return语句。所以,基本上你的

    推荐文章