【发布时间】:2017-02-02 21:06:00
【问题描述】:
代码正在尝试将大型 uint8_t 数组序列化为二进制字符流。我应该在缓冲区中有足够的空间来复制这些数据;为什么我会收到这些错误?发布的是带有输出错误的完整可运行代码。使用的 valgrind 命令是:
valgrind --leak-check=yes --track-origins=yes ./prog
主要:
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "stdint.h"
#include <unistd.h>
#define MAX_FRAME_SIZE 9236
#define DAT_LEN 8202
void create_bit_stream(uint8_t frame[], size_t frame_size, char *frame_bits)
{
/*
* Takes in uint8_t array of data and converts to binary stream of characters
* frame : input array of uint8_t type data
* frame_size : size_t length of frame --> sizeof(frame)/sizeof(frame[0])
* frame_bits : pointer for returning the character string
*
* RETURNS string of binary values generated from input array
*/
uint8_t tmp[frame_size];
memset(tmp,0,frame_size);
memcpy(tmp,frame,frame_size);
// char bit_string[frame_size*8+1];
char *bit_string = malloc(frame_size*8+1);
memset(bit_string,'\0',frame_size*8 + 1);
for (int i = 0; i < frame_size; i++)
{
for (int j = 0; j < 8; j++)
{
bit_string[i*8+j] = '0' + (tmp[i] >> 7);
tmp[i] <<= 1;
}
}
bit_string[frame_size*8] = '\0';
strcpy(frame_bits, bit_string);
free(bit_string);
return;
}
int main(int argc, char *argv[])
{
char *frame_bits = malloc(MAX_FRAME_SIZE + 1);
if(!frame_bits)
{exit(EXIT_FAILURE);}
memset(frame_bits,'\0',MAX_FRAME_SIZE + 1);
uint8_t *DAT_frame = malloc(DAT_LEN);
if(!DAT_frame)
{exit(EXIT_FAILURE);}
memset(DAT_frame,0,DAT_LEN);
//fill with arbitrary data
for(int i = 0; i < DAT_LEN; i++)
{
DAT_frame[i] = i % 255;
}
create_bit_stream(DAT_frame, DAT_LEN, frame_bits);
free(frame_bits); free(DAT_frame);
return 0;
}
错误:
==2994== Invalid write of size 1
==2994== at 0x4C31060: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2994== by 0x40088B: create_bit_stream (stack.c:36)
==2994== by 0x400993: main (stack.c:61)
==2994== Address 0x5205455 is 0 bytes after a block of size 9,237 alloc'd
==2994== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2994== by 0x4008CE: main (stack.c:45)
==2994==
==2994== Source and destination overlap in strcpy(0x5203040, 0x52074f0)
==2994== at 0x4C310E6: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2994== by 0x40088B: create_bit_stream (stack.c:36)
==2994== by 0x400993: main (stack.c:61)
【问题讨论】:
-
这不是你的问题,但仅供参考,
sizeof(char)按定义为 1,因此foo * sizeof(char)是多余的,并且代码味道不好。 -
你将不得不减少这个问题中的太多噪音
-
@RyanHaining 不确定您要我删除什么。有两个指针初始化和一个非常小的函数。这里实际上没有任何多余的东西。
-
进一步解释:您可能不认为
sizeof(uint8_t)与sizeof(char)相同,但它必须是,因为char不能小于 比@987654330 @(需要CHAR_BIT >= 8),如果更大(即CHAR_BIT > 8),则要求实现不提供uint8_t。 -
我可以重现问题(在放回
#includes 和顶级文件结构后——请不要让人们以后这样做,提供minimal but complete example)并且正在调查。