需要帮助理解这个代码的输出

问题描述:

看到我的代码是需要帮助理解这个代码的输出

#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?

由于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:这是一个编程错误的典型例子,它是数百个可以被用于严重破坏的严重可利用漏洞的核心......事实上,理解这个概念可能是最重要的漏洞之一认识的重要方面 –