您分配了一个 length/8 元素数组,但您在索引 0 到 length - 1 处写入 => 您从分配的数组中写入,行为未定义
替换
char* result = (char*)malloc(length / 8);
通过
char* result = malloc(length);
或者当然改变你的循环
目前您也很可能会从 b 管理的数组中读出,因为您每次进步 8 个字符,所以您从索引 0 调用 strtol,然后是 8 ...然后8*(length-1),将数组读取为未定义行为
其他问题
- 您将
char 和long 分配给您的数组,您真的要这样做吗?
-
strtol 肯定不会像你在输入字符串中那样产生你期望的值
根据您的评论,一种方法是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* binaryToString(char * b)
{
size_t n = (strlen(b) + 7) / 8;
char * result = malloc(n + 1);
size_t i;
for (i = 0; i < n; i++, b += 8) {
char s[9];
strncpy(s, b, 8);
s[8] = 0;
result[i] = (char) strtol(s, NULL, 2);
}
result[i] = 0;
return result;
}
int main(int argc, char ** argv)
{
while (--argc) {
argv += 1;
char * r = binaryToString(*argv);
printf("%s -> %s\n", *argv, r);
free(r);
}
return 0;
}
我使用缓冲区复制每个最多 8 个字符的块,以不修改输入字符串。
警告:
- 假设 char 可以支持从 0 到 255 的值(请参阅
CHAR_BIT)
- 即使 strtol 允许这样做,也不会检查输入字符串的有效性。
- 如果输入字符串的长度不是 8 的倍数但大于 8,即使没有未定义的行为,结果也不是预期的。
- 结果可以包含不可读的字符,包括在分配数组的最后位置放置的空字符之前的空字符。
编译和执行:
pi@raspberrypi:/tmp $ gcc -Wall -g cv.c
pi@raspberrypi:/tmp $
pi@raspberrypi:/tmp $ ./a.out 01100001011100110110010001100110 100001 0110000100000000011100110110010001100110
01100001011100110110010001100110 -> asdf
100001 -> !
0110000100000000011100110110010001100110 -> a
pi@raspberrypi:/tmp $
pi@raspberrypi:/tmp $ valgrind ./a.out 01100001011100110110010001100110 100001 0110000100000000011100110110010001100110
==12327== Memcheck, a memory error detector
==12327== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12327== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==12327== Command: ./a.out 01100001011100110110010001100110 100001 0110000100000000011100110110010001100110
==12327==
01100001011100110110010001100110 -> asdf
100001 -> !
0110000100000000011100110110010001100110 -> a
==12327==
==12327== HEAP SUMMARY:
==12327== in use at exit: 0 bytes in 0 blocks
==12327== total heap usage: 4 allocs, 4 frees, 1,037 bytes allocated
==12327==
==12327== All heap blocks were freed -- no leaks are possible
==12327==
==12327== For lists of detected and suppressed errors, rerun with: -s
==12327== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi@raspberrypi:/tmp $
(在 0110000100000000011100110110010001100110 的情况下,结果的第二个字符是空字符,因此不会打印下一个字符)