二維數組賦值給一維數組,子函數返回獲取臨時變量的指針導致問題

1 說明

在C語言中,如果從子函數獲取指針,然後將指針拷貝給其他數據,容易出現拷貝不成功。這是因爲子函數的變量,分配在棧上,當子函數退出時,對應的變量也生命週期結束。如果此時在將指針指向的數據拷貝,容易出現拷貝不成功。

2 問題代碼示例

#include <stdio.h>

unsigned char* GetArray(int num)
{
        unsigned char code[3][10] =
        {
                {0x01, 0xa2, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a},
                {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a},
                {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a},
        };

        return code[num];
}


int main(int argc, char** argv)
{        
        int i = 0;
        unsigned char buf[10];
        
        memset(buf, 0, sizeof(buf) / sizeof(buf[0]));
        memcpy(buf, GetArray(1), 10);
        for (i = 0; i < 10; i++)
        {
                printf("buf[%d] = %02d, 0x%02x\n", i, buf[i], buf[i]);
        } 
}

代碼看起來沒什麼問題,但是,對於子函數GetArray, 二維素組是一個臨時變量,函數返回拷貝的是臨時變量的地址。這樣,如果在簡單的單線程程序不會有問題,但是在多線程或者大一些的程序中如此操作,那麼,返回的指針,指向的地址,數據將會變爲不可預計的。

3 修改方法

將子函數中,定義的二維數組,改爲 static 或者全局變量,如此,GetArray 函數返回的地址,是一直存在,不會隨着子函數結束而導致改地址的數據改變。

unsigned char* GetArray(int num)
{
        static unsigned char code[3][10] =
        {
                {0x01, 0xa2, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a},
                {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a},
                {0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a},
        };

        return code[num];
}

測試結果

將修改後的程序編譯並運行,結果如下,正常獲取數據。

buf[0] = 17, 0x11
buf[1] = 18, 0x12
buf[2] = 19, 0x13
buf[3] = 20, 0x14
buf[4] = 21, 0x15
buf[5] = 22, 0x16
buf[6] = 23, 0x17
buf[7] = 24, 0x18
buf[8] = 25, 0x19
buf[9] = 26, 0x1a
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章