2011-10-31 117 views
0

看到我的代碼是需要幫助理解這個代碼的輸出

#include <stdio.h> 
#include<stdlib.h> 
#include<sys/stat.h> 
int main(int argc, char**argv) { 

    unsigned char *message = NULL; 

    struct stat stp = { 0 }; 
    stat("huffman.txt", &stp); 
    /*determine the size of data which is in file*/ 
    int filesize = stp.st_size; 
    printf("\nFile size id %d\n", filesize); 

    FILE* original_fileptr = fopen("huffman.txt", "r"); 
    message = malloc(filesize); 
    fread(message, 1, filesize, original_fileptr); 
    printf("\n\tEntered Message for Encode is %s= and length %d", message,strlen(message)); 

    return 0; 
} 

這裏huffman.txt有大小20個字節,下面的字符是否有

άSUä5Ñ®qøá「F「œ

此代碼的

輸出是

File size id 20 

     Entered Message for Encode is ά­SUä5Ñ®qøá"F„œ= and length 21 

現在q如果size是20,那麼爲什麼長度是21?

回答

6

由於C沒有本地字符串,只有字符數組,並且有一個隱藏的無處不在的假設,即最後一個數組成員爲零。

因爲你違反了這一假設通過讀取只有20字節到20個元素的數組,沒有考慮到最後一個字節是否爲零,然後使用功能,如%sstrlen,你基本上是未定義的行爲。

得到21的答案是純粹的運氣;任何事情(更糟)都可能發生。

正確的代碼可能是這樣的(假設該文件是一個文本文件):

char * buf = calloc(filesize + 1, 1); /* yay, already zeroed! */ 
fread(buf, 1, filesize, fp); 
printf("File contents: '%s'\nFile content size: %u.\n", buf, strlen(buf)); 

如果你正在讀任意(「二進制」)的文件,這通常不會產生預期的結果(除非你知道會發生什麼)。

+1

「更糟」的範圍從分段違規到信息披露。 – ninjalj

+2

@ninjalj:這是一個編程錯誤的典型例子,它是數百個可以被用於嚴重破壞的嚴重可利用漏洞的核心......事實上,理解這個概念可能是最重要的漏洞之一認識的重要方面 –