为什么Valgrind报告地址0x522da08在大小为8 alloc'的块之后是0字节;D

为什么Valgrind报告地址0x522da08在大小为8 alloc'的块之后是0字节;D,c,dynamic-memory-allocation,C,Dynamic Memory Allocation,我很难理解为什么Valgrind不断报告我使用的结构分配的错误 以下是我收到的以下错误: ==26932== Memcheck, a memory error detector ==26932== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==26932== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==26932==

我很难理解为什么Valgrind不断报告我使用的结构分配的错误

以下是我收到的以下错误:

==26932== Memcheck, a memory error detector
==26932== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==26932== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==26932== Command: ./mirsa_genkeys -k sample
==26932== Parent PID: 11465
==26932==
==26932== Invalid write of size 8
==26932==    at 0x108EE9: mr_make_keys (mirsa_lib.c:78)
==26932==    by 0x108BB3: main (mirsa_genkeys.c:44)
==26932==  Address 0x522da08 is 0 bytes after a block of size 8 alloc'd
==26932==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26932==    by 0x108EC3: mr_make_keys (mirsa_lib.c:75)
==26932==    by 0x108BB3: main (mirsa_genkeys.c:44)
==26932==
==26932== Invalid read of size 1
==26932==    at 0x4C371F8: mempcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26932==    by 0x4ECA53B: _IO_default_xsputn (genops.c:404)
==26932==    by 0x4EC7AA2: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1287)
==26932==    by 0x4EBB9E6: fwrite (iofwrite.c:39)
==26932==    by 0x108F1F: mr_make_keys (mirsa_lib.c:81)
==26932==    by 0x108BB3: main (mirsa_genkeys.c:44)
==26932==  Address 0x522da3f is 17 bytes before a block of size 8 alloc'd
==26932==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26932==    by 0x108ED1: mr_make_keys (mirsa_lib.c:76)
==26932==    by 0x108BB3: main (mirsa_genkeys.c:44)
==26932==
==26932== Invalid read of size 1
==26932==    at 0x4C3720A: mempcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26932==    by 0x4ECA53B: _IO_default_xsputn (genops.c:404)
==26932==    by 0x4EC7AA2: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1287)
==26932==    by 0x4EBB9E6: fwrite (iofwrite.c:39)
==26932==    by 0x108F1F: mr_make_keys (mirsa_lib.c:81)
==26932==    by 0x108BB3: main (mirsa_genkeys.c:44)
==26932==  Address 0x522da3d is 19 bytes before a block of size 8 alloc'd
==26932==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26932==    by 0x108ED1: mr_make_keys (mirsa_lib.c:76)
==26932==    by 0x108BB3: main (mirsa_genkeys.c:44)
以下是我用于代码的结构:

    typedef struct key_s {
    uint64_t key;           
    uint64_t nonce;        
    } key_t;
这是我的代码,我尝试使用一组给定的数字生成公钥和私钥

       bool mr_make_keys( uint64_t p, uint64_t q, const char * user){

        struct key_s* public;
        struct key_s* private;
        FILE *public_file;
        FILE *private_file;
        char *public_filename;
        char *private_filename;
        // replace with p
        uint64_t first = 53;
        // replace with q
        uint64_t second = 71;
        uint64_t n= first * second;
        uint64_t phi = (first - 1)*(second - 1);
        uint64_t e;
        uint64_t d;

        int x, y;
        int g = gcdExtended(first, second, &x, &y);
        e = y;
        printf("%d %d gcd(%ld, %ld) = %d\n",x,y ,first, second, g);

        if (n > ULONG_MAX || user == NULL || user[-1] != '\0')
                return false;

        d = (1 + ((e-1) * phi))/e;
        printf("%lu\n", d);
        public_filename = (char*) malloc(sizeof(char)*(strlen(user)+5));
        strcpy(public_filename, user);
        strcat(public_filename, ".pub");
        public_file = fopen(public_filename, "w");
        private_filename = (char*) malloc(sizeof(char)*(strlen(user)+5));
        strcpy(private_filename, user);
        strcat(private_filename, ".pvt");
        private_file = fopen(private_filename, "w");
        public = malloc( sizeof(struct key_s*));
        private = malloc( sizeof(struct key_s*));
        public->key = e;
        public->nonce = n;
        private->key = d;
        public->key = n;
        fwrite(public,sizeof(uint64_t), sizeof(public),public_file );
        fwrite(private , sizeof(uint64_t), sizeof(private), private_file);
        free(public_filename);
        free(private_filename);
        free(public);
        free(private);
        fclose(public_file);
        fclose(private_file);
        return true;
     }
有人能向我解释错误以及我如何修复错误吗?

这里有一个问题:

    public = malloc( sizeof(struct key_s*));
    public->key = e;
您分配的空间是指针的大小(8字节,64位),而不是结构的大小

养成这种习惯:

    public = malloc(sizeof *public);
这里有一个问题:

    public = malloc( sizeof(struct key_s*));
    public->key = e;
您分配的空间是指针的大小(8字节,64位),而不是结构的大小

养成这种习惯:

    public = malloc(sizeof *public);

您正在使用
%ld
格式规范先输出
uint64\t,然后输出。它应该是
%llu
,但不会导致问题。更好的方法是使用
PRIu64
。您正在使用
%ld
格式规范来输出
uint64\t first、second。它应该是
%llu
,但不会导致问题。更好的方法是,在将其更改为PRIu64后使用它。我仍然收到相同的错误,现在它说“地址0x522dcaf在一个大小为16的块分配之前是17个字节。”
fwrite
调用中的参数没有任何意义。将其更改为该值后。我仍然得到同样的错误,现在它说“地址0x522dcaf在一个大小为16的块之前是17个字节”。调用
fwrite
中的参数没有任何意义。