Cast a type with a small memory space to a bigger one
這是一個很常見的錯誤,可是我還是犯了 (...sigh)
我當然不是在下面的程式碼犯錯囉,但因為犯錯的程式是工作上的程式,不能貼出來,所以稍作整理,寫出下面的那個「錯誤」程式碼,以資提醒... (為甚麼我有再犯的預感 ...)
下面的程式哪裡有問題:
#include "stdio.h"
#include "stdlib.h"
struct test
{
unsigned char a;
unsigned char b;
unsigned char c;
};
int main()
{
struct test tmp;
printf("Please enter three number.\n");
printf("Each number should be 0~255\n");
scanf("%d %d %d", &(tmp.a), &(tmp.b), &(tmp.c) );
printf("%d %d %d\n", tmp.a, tmp.b, tmp.c);
return 0;
}
當我們輸入 1 2 3,顯示也是正常的 1 2 3,看起來一點問題也沒有。
真的嗎????
讓我們改一下程式碼如下:
scanf("%d %d %d", &(tmp.c), &(tmp.b), &(tmp.a) );
printf("%d %d %d\n", tmp.a, tmp.b, tmp.c);
簡單來說,只是把讀取順序反過來,然後一樣輸入 1 2 3,結果答案是 3 0 0 而不是 3 2 1。到底發生了什麼事情???
首先,當我們用 scanf 進行讀取的時候,是以 int 的方式讀入,也就是說總共讀入了 4 個 byte,所以第一段程式碼可以用下面的那張圖來表示:
-----------------------byte
--------------------+--------+-------+--------+
--------------------|---a-----|---b---|---c-----|
--------------------+--------+-------+--------+
--------------------+--------+--------+--------+-------+
input 1 ----- |---1-----|---0----|---0----|---0---|
--------------------+--------+--------+--------+--------+
-------------------------------+--------+-------+---------+-------+
input 2 -----------------|----2----|---0---|---0-----|---0---|
+----------------------------+--------+---------+-------+--------+
+---------------------------------------+--------+--------+-------+----------+
input 3-----------------------------|----3----|----0---|---0---|----0----|
+---------------------------------------+--------+--------+-------+----------+
所以讀出來的數字沒問題,但從上面的這張圖應該已經看出危險所在,那就是讀取數字的時候居然寫到了不屬於 structure 的記憶體位置。所以我們在第二次作實驗的時候,就會發現嚴重的問題。圖示如下:
-----------------------byte
--------------------+--------+-------+--------+
--------------------|---a-----|---b---|---c-----|
--------------------+--------+-------+--------+
+---------------------------------------+--------+--------+-------+----------+
input 1-----------------------------|----3----|----0---|---0---|----0----|
+---------------------------------------+--------+--------+-------+----------+
-------------------------------+--------+-------+---------+-------+
input 2 -----------------|----2----|---0---|---0-----|---0---|
+----------------------------+--------+---------+-------+--------+
--------------------+--------+--------+--------+-------+
input 3 ----- |---1-----|---0----|---0----|---0---|
--------------------+--------+--------+--------+--------+
看到了嗎?b, c 的值被蓋掉了!!這就是為甚麼印出來是 3 0 0 的原因了~
簡單 ... 但還是錯了
我當然不是在下面的程式碼犯錯囉,但因為犯錯的程式是工作上的程式,不能貼出來,所以稍作整理,寫出下面的那個「錯誤」程式碼,以資提醒... (為甚麼我有再犯的預感 ...)
下面的程式哪裡有問題:
#include "stdio.h"
#include "stdlib.h"
struct test
{
unsigned char a;
unsigned char b;
unsigned char c;
};
int main()
{
struct test tmp;
printf("Please enter three number.\n");
printf("Each number should be 0~255\n");
scanf("%d %d %d", &(tmp.a), &(tmp.b), &(tmp.c) );
printf("%d %d %d\n", tmp.a, tmp.b, tmp.c);
return 0;
}
當我們輸入 1 2 3,顯示也是正常的 1 2 3,看起來一點問題也沒有。
真的嗎????
讓我們改一下程式碼如下:
scanf("%d %d %d", &(tmp.c), &(tmp.b), &(tmp.a) );
printf("%d %d %d\n", tmp.a, tmp.b, tmp.c);
簡單來說,只是把讀取順序反過來,然後一樣輸入 1 2 3,結果答案是 3 0 0 而不是 3 2 1。到底發生了什麼事情???
首先,當我們用 scanf 進行讀取的時候,是以 int 的方式讀入,也就是說總共讀入了 4 個 byte,所以第一段程式碼可以用下面的那張圖來表示:
-----------------------byte
--------------------+--------+-------+--------+
--------------------|---a-----|---b---|---c-----|
--------------------+--------+-------+--------+
--------------------+--------+--------+--------+-------+
input 1 ----- |---1-----|---0----|---0----|---0---|
--------------------+--------+--------+--------+--------+
-------------------------------+--------+-------+---------+-------+
input 2 -----------------|----2----|---0---|---0-----|---0---|
+----------------------------+--------+---------+-------+--------+
+---------------------------------------+--------+--------+-------+----------+
input 3-----------------------------|----3----|----0---|---0---|----0----|
+---------------------------------------+--------+--------+-------+----------+
所以讀出來的數字沒問題,但從上面的這張圖應該已經看出危險所在,那就是讀取數字的時候居然寫到了不屬於 structure 的記憶體位置。所以我們在第二次作實驗的時候,就會發現嚴重的問題。圖示如下:
-----------------------byte
--------------------+--------+-------+--------+
--------------------|---a-----|---b---|---c-----|
--------------------+--------+-------+--------+
+---------------------------------------+--------+--------+-------+----------+
input 1-----------------------------|----3----|----0---|---0---|----0----|
+---------------------------------------+--------+--------+-------+----------+
-------------------------------+--------+-------+---------+-------+
input 2 -----------------|----2----|---0---|---0-----|---0---|
+----------------------------+--------+---------+-------+--------+
--------------------+--------+--------+--------+-------+
input 3 ----- |---1-----|---0----|---0----|---0---|
--------------------+--------+--------+--------+--------+
看到了嗎?b, c 的值被蓋掉了!!這就是為甚麼印出來是 3 0 0 的原因了~
簡單 ... 但還是錯了
留言
張貼留言