C中的malloc()内存损坏
malloc()在下面的代码中给了我一个错误。我用了valgrind,但仍然没有用。我是C语言的初学者,我的队友和我都在尝试实现SHA1算法,但有些东西我们都不理解,而且花了很多时间在这上面。这是函数中有错误的部分-C中的malloc()内存损坏,c,memory,malloc,sha1,memory-corruption,C,Memory,Malloc,Sha1,Memory Corruption,malloc()在下面的代码中给了我一个错误。我用了valgrind,但仍然没有用。我是C语言的初学者,我的队友和我都在尝试实现SHA1算法,但有些东西我们都不理解,而且花了很多时间在这上面。这是函数中有错误的部分- /* * Returns an array of chunks on the heap from the message */ static unsigned char **sha1_chunkify(const unsigned char *message, const u
/*
* Returns an array of chunks on the heap from the message
*/
static unsigned char **sha1_chunkify(const unsigned char *message, const uint64_t message_length)
{
long num_chunks = message_length / 64; //breaking it down into 64 byte chunks
printf("%lu %ld\n", message_length, num_chunks);
unsigned char **chunks = malloc (num_chunks * sizeof(*chunks)); //Error is coming over here
for (int i = 0; i < num_chunks; i++) {
chunks[i] = malloc (64 * sizeof(*chunks[i])); //Or sometimes over here.
for (int j = 0; j < 64; j++) {
chunks[i][j] = message[64 * i + j];
}
}
return chunks;
}
Valgrind显示了以下内容-
3
mytry.c
==16688== Invalid write of size 1
==16688== at 0x401EA6: append_zeroes (sha1.c:155)
==16688== by 0x401F1D: sha1_pad (sha1.c:177)
==16688== by 0x401FB7: sha1 (sha1.c:200)
==16688== by 0x400C72: snap_file (snap.c:40)
==16688== by 0x4012F7: snap (snap.c:143)
==16688== by 0x401852: snap_all (snap.c:220)
==16688== by 0x40222E: main (nako.c:24)
==16688== Address 0x5220720 is 0 bytes after a block of size 1,408 alloc'd
==16688== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16688== by 0x401F7B: sha1 (sha1.c:195)
==16688== by 0x400C72: snap_file (snap.c:40)
==16688== by 0x4012F7: snap (snap.c:143)
==16688== by 0x401852: snap_all (snap.c:220)
==16688== by 0x40222E: main (nako.c:24)
==16688==
==16688== Invalid write of size 1
==16688== at 0x401E6A: append_msg_len (sha1.c:142)
==16688== by 0x401F34: sha1_pad (sha1.c:179)
==16688== by 0x401FB7: sha1 (sha1.c:200)
==16688== by 0x400C72: snap_file (snap.c:40)
==16688== by 0x4012F7: snap (snap.c:143)
==16688== by 0x401852: snap_all (snap.c:220)
==16688== by 0x40222E: main (nako.c:24)
==16688== Address 0x5220758 is not stack'd, malloc'd or (recently) free'd
==16688==
1472 23
valgrind: m_mallocfree.c:277 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.
==16688== at 0x38050BAC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==16688== by 0x38050D06: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==16688== by 0x3805B36A: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==16688== by 0x3805D2D7: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==16688== by 0x380216D4: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==16688== by 0x380218A2: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==16688== by 0x3809DC03: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==16688== by 0x380AC87C: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable
==16688== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16688== by 0x401D94: sha1_chunkify (sha1.c:118)
==16688== by 0x401FCA: sha1 (sha1.c:202)
==16688== by 0x400C72: snap_file (snap.c:40)
==16688== by 0x4012F7: snap (snap.c:143)
==16688== by 0x401852: snap_all (snap.c:220)
==16688== by 0x40222E: main (nako.c:24)
我已经经历了几个线程,但错误仍然存在。如果以前有人问过,我道歉。我找不到同样的。先谢谢你
下面是函数append_zero和append_msg_len-
/*
* Pad the message with its length.
* The input lengths are in bytes, while the padding, in accordance with
* the SHA1 algorithm, is done in bits.
*/
static inline void append_msg_len(unsigned char *message,
uint64_t *message_length,
uint64_t original_msglen)
{
int shift = 56;
while (shift >= 0) {
/* Add the next 8 bits. */
message[*message_length] = (8 * original_msglen >> shift) & 0xff;
shift -= 8;
*message_length += 1;
}
}
/*
* Appends enough zeroes until the message has just enough room for appending
* the message length, i.e, length 448 mod 512
*/
static inline void append_zeroes(unsigned char *message, uint64_t *message_length)
{
while (*message_length % 64 != 56) {
message[*message_length] = (unsigned char) 0x00;
*message_length += 1;
}
}
查看此代码:
long num_chunks = message_length / 64; //breaking it down into 64 byte chunks
例如,如果我们使用message\u length
=63,num\u chunks
变为零,这显然是错误的。如果您改为使用:
long num_chunks = (message_length + 63) / 64; //breaking it down into 64 byte chunks
您将获得正确数量的块,希望您的其余代码表现良好。valgrind输出非常清楚地表明问题不在您发布的代码中,而是在
append\u zeroes()
中。这一行:long num\u chunks=message\u length/64
是一个整数除法,因此会导致num_chunks比实际的块数少1,因为任何分数都被截断。发布的代码包含magic
数字64。使用magic
数字会使代码更难理解,并且在执行维护时会引起严重的麻烦。强烈建议使用枚举或#define来创建一个有意义的名称,并在整个代码中使用该有意义的名称。@user3629249:不,这行非常好。建议将:long num_chunks=message_length/64
替换为:long num_chunks=(message_length+63)/64
如果消息长度不是64的倍数,则这只是一个问题,并且在本代码中,只会导致一些数据丢失,这可能是错误的,但不会导致所询问的错误。此函数中的代码不会写入超出分配空间的末尾。假设消息长度
不总是64的倍数,我想其他代码(如附加零
)可以正确计算块并尝试使用未分配的块?但是我们在猜测,没有append_zero
code。当然这是可能的。在无效写入位置有相当多的堆栈跟踪,问题可能在任何地方。。。
long num_chunks = (message_length + 63) / 64; //breaking it down into 64 byte chunks