Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 添加未使用变量的随机行为_C - Fatal编程技术网

C 添加未使用变量的随机行为

C 添加未使用变量的随机行为,c,C,我真的不知道如何命名这个问题,问题是我在下面的代码中看到了一些严重的魔法 在这里,我放置了所有相关的代码片段及其输出 void persist_receipt(Receipt * receipt, char * path) { int i, fd; unsigned char block_fname[64]; fd = open( ".receipt", O_RDWR | O_CREAT, 0777); printf("1.fd=%i\n", fd);

我真的不知道如何命名这个问题,问题是我在下面的代码中看到了一些严重的魔法

在这里,我放置了所有相关的代码片段及其输出

void persist_receipt(Receipt * receipt, char * path)
{
    int i, fd;
    unsigned char block_fname[64];

    fd = open( ".receipt", O_RDWR | O_CREAT, 0777);
    printf("1.fd=%i\n", fd);
    // Write receipt header
    write(fd, receipt->hash, 32);
    write(fd, receipt->name, 256);
    write(fd, &receipt->size, sizeof(int));

    printf("2.fd=%i\n", fd);

    for(i=0; i<receipt->size; i++)
    {
            printf("3.fd=%i\n", fd);
            sha2hexf(block_fname, receipt->blocks[i].hash);
            printf("4.fd=%i\n", fd);
            write(fd, block_fname, 64);
    }

    close(fd);
}
这个随机文件描述符的值丢失了,这是怎么回事?由于他随机将其值更改为0,它会将哈希输出到控制台,但不应该发生

有趣的部分来了!如果我只声明一个新变量。假设我声明了一个新的整数,如下所示:

void persist_receipt(Receipt * receipt, char * path)
{
    int i, fd, p;
    unsigned char block_fname[64];

    fd = open( ".receipt", O_RDWR | O_CREAT, 0777);
    printf("1.fd=%i\n", fd);
    // Write receipt header
    write(fd, receipt->hash, 32);
    write(fd, receipt->name, 256);
    write(fd, &receipt->size, sizeof(int));

    printf("2.fd=%i\n", fd);

    for(i=0; i<receipt->size; i++)
    {
            printf("3.fd=%i\n", fd);
            sha2hexf(block_fname, receipt->blocks[i].hash);
            printf("4.fd=%i\n", fd);
            write(fd, block_fname, 64);
    }

    close(fd);
}
我希望有人能解释一下幕后发生的事情。因为对我来说,这似乎是一种相当黑暗的魔法,就在那里。我怀疑有什么可疑的'sha2hexf'函数,所以在这里我也放了代码,特别是可疑的部分是里面的sprintf调用

void sha2hexf(unsigned char *outbuf, unsigned char *hash) {
int i;
    for (i = 0; i < 32; i++) {
        sprintf((char*)outbuf, "%.2x", hash[i]);
        outbuf += 2;
    }
}
void sha2hexf(无符号字符*extuf,无符号字符*hash){
int i;
对于(i=0;i<32;i++){
sprintf((char*)exputf,“%.2x”,散列[i]);
f+=2;
}
}

有什么真正的解释吗?

您的函数
sha2hexf
显然超出了您传入的缓冲区。终止64字节字符串为空(因此缓冲区中至少需要65字节)

通常,编译器会反向排列堆栈,因此您会得到:

block_fname (64 bytes) | fd (4 bytes) | i (4 bytes)

                         ^ Overflow hits the first byte of 'fd', which zeros it
                           a little-endian architecture (if fd less than 256).

sha2hexf正在跨越extuf的边界(也称为block_fname),因为sprintf在每个循环中都附加了“\0”(您可以通过增加extuf来处理它,但不是在最后一次循环运行中!)。
因此,您需要的缓冲区可以容纳65个字符。

如果您的书写超出了您的边界,那么可能会出现奇怪而奇妙的行为。通过valgrind运行您的程序[并发布更多代码]非常感谢!监督这件事太愚蠢了。
void sha2hexf(unsigned char *outbuf, unsigned char *hash) {
int i;
    for (i = 0; i < 32; i++) {
        sprintf((char*)outbuf, "%.2x", hash[i]);
        outbuf += 2;
    }
}
block_fname (64 bytes) | fd (4 bytes) | i (4 bytes)

                         ^ Overflow hits the first byte of 'fd', which zeros it
                           a little-endian architecture (if fd less than 256).