为什么要更新此int?

时间:2015-07-04 18:26:06

标签: c

在我的学校项目(多线程shell)上我试图在代码中添加一些调试语句。我遇到了一个有趣的情况,并想知道它为什么会发生。

int signals(void)
{
    if (tcb[curTask].signal)
    {
        int beforeSignal = tcb[curTask].signal;
        if (tcb[curTask].signal & mySIGINT)
        {
            tcb[curTask].signal &= ~mySIGINT; // clears the mySIGINT from the signals
            (*tcb[curTask].sigIntHandler)();
        }
        if (tcb[curTask].signal & mySIGCONT)
        {
            tcb[curTask].signal &= ~mySIGCONT; // clears the mySIGCONT from the signals
            (*tcb[curTask].sigContHandler)();
        }
        if (tcb[curTask].signal & mySIGTERM)
        {
            tcb[curTask].signal &= ~mySIGTERM; // clears the mySIGTERM from the signals
            (*tcb[curTask].sigTermHandler)();
        }
        if (tcb[curTask].signal & mySIGTSTP)
        {
             tcb[curTask].signal &= ~mySIGTSTP; // clears the mySIGTSTP from the signals
            (*tcb[curTask].sigTstpHandler)();
        }
        if (DEBUG) {
            printf("\nSignals:\n\tBefore: %s\n\tAfter: %s",byte_to_binary(beforeSignal), byte_to_binary(tcb[curTask].signal));
        }
    }
    return 0;
}

TCB是一个结构:

typedef struct                          // task control block
{
    char* name;                         // task name
    int (*task)(int,char**);        // task address
    int state;                          // task state
    int priority;                       // task priority (project 2)
    int argc;                           // task argument count (project 1)
    char** argv;                        // task argument pointers (project 1)
    int signal;                         // task signals (project 1)
    void (*sigContHandler)(void);   // task mySIGCONT handler
    void (*sigIntHandler)(void);    // task mySIGINT handler
    void (*sigKillHandler)(void);   // task mySIGKILL handler
    void (*sigTermHandler)(void);   // task mySIGTERM handler
    void (*sigTstpHandler)(void);   // task mySIGTSTP handler
    TID parent;                         // task parent
    int RPT;                                // task root page table (project 5)
    int cdir;                           // task directory (project 6)
    Semaphore *event;                   // blocked task semaphore
    void* stack;                        // task stack
    jmp_buf context;                    // task context pointer
} TCB;

和byte_to_binary将int转换为二进制字符串。

const char *byte_to_binary(int x)
{
    static char b[9];
    b[0] = '\0';

    int z;
    for (z = 128; z > 0; z >>= 1)
    {
        strcat(b, ((x & z) == z) ? "1" : "0");
    }

    return b;
}

当调试语句打印时,它看起来像这样:

Signals:
    Before: 000000000
    After: 000000000

打印分配了beforeSignal int的信号,并在conditial / masking block之后打印:

Signals:
    Before: 00001000
    After: 00000000

因此看起来foreCignal正在通过条件中的屏蔽操作进行更新。我认为整数总是按值传递,所以我不明白为什么int从它的初始值改变了。我确信有一个简单的方法来获取int的“副本”,它不会反映原始值,我很高兴知道它。

1 个答案:

答案 0 :(得分:3)

问题是您将byte_to_binary()函数的结果放在static缓冲区中。实际调用printf()的语句会在将控制权转移到byte_to_binary()之前同时调用printf()。所以printf()只显示两次相同的缓冲区。

您需要执行类似byte_to_binary()之类的操作,然后返回动态分配的字符串,然后再将其释放(在这种情况下,您无法在调用时轻松使用它printf()没有内存泄漏),或者您需要更改接口以便将输出缓冲区传递到byte_to_binary()。只需让byte_to_binary()返回传入的指针,然后就可以像你现在一样从printf()调用它。