如果我理解正确,你试图在两个定义的点分割一个字符串,对吧?看来你有binary
一个字符串,它具有以下格式:
XXXXYYYYYYZZZ0
^ ^^^
| | | \String terminator
| | \Offset
| \Tag
\Index
各部分的长度当然只是一个例子,因为我没有看到你的常量。但根据我的例子,你可能有这样定义的变量(指定它们的字符串结尾):
#define INDEX 4
#define TAG 10
#define OFFSET 13
现在第一个问题是什么,为什么它会立即不适合你:你是没有正确构建resultsTag
。但我们先看看resultsIndex
。
resultsIndex
种作品,但它也没有做到正确。我会解释你为什么。你这样做:
resultsIndex = (char *)malloc(sizeof(char) * INDEX);
for(i = 0; i < INDEX; i++){
resultsIndex[i] = binary[i];
}
做些什么:
- 分配
INDEX
(4在我的例子)字符的结果字符串。
- 仅从0到
INDEX
(4)循环,即INDEX - 1
(3)包含并复制数据。
因此i
将在循环中得到值0..1..2..3。这意味着它会将binary
中位置0-3的所有字符复制到resultsIndex
中的位置0-3。
这一部分之后,resultsIndex
与大小的4个字符定义(如果我们继续上面我举的例子值),看起来像这样:
____ << defined size
XXXX
...这是该指数部分您复制的字符串。但是,这里有一个错误就是已经没有字符串终止符了!它应该是这样的:
_____ << defined size
XXXX0
^
\string terminator
一个字符串结束就是告诉到任何/谁是读书迟字符串,它在这里结束,他们不得不停止在这里看书,否则他们将读取超出结尾。
然而,因为没有什么是独一无二的,但通常是由内存的其他部分包围着,我想这正好是这样的:
____ << defined size
XXXX00000000000...
^ ^
| \you were lucky that those null bytes were around
\this part you actually allocated
但你不应该依赖于这一点。它也可能是这个样子的:
____ << defined size
XXXXgarbage...
...那么它会打印XXXXgarbage
,而不是仅仅XXXX
。或者:
____ << defined size
XXXX| << here the memory block actually ends
...然后它会崩溃试图打印它。
因此,要解决这个问题,你必须预留一个多字节和填充它与零值,它作为字符串结束:
resultsIndex = (char *)malloc(sizeof(char) * (INDEX + 1));
for(i = 0; i < INDEX; i++){
resultsIndex[i] = binary[i];
}
resultsIndex[INDEX] = 0; // string terminator
OK,现在回到resultsTag
。在我上面的例子中(看起来你是这样做的),我的常量TAG
被定义为10
,它基本上是标记之前的部分(索引:4)和标记本身(6)在一起的长度。但标签本身只有6个字符(= TAG - INDEX
)。
此刻,你正在做这个(我删除了清晰一些事情):
resultsTag = (char *)malloc(sizeof(char) * TAG);
for(t = INDEX; t < TAG + 1; t++){
resultsTag[t] = binary[t];
printf("resultsTag[i] %c\n", resultsTag[t]);
}
做些什么:
- 分配
TAG
(在我的例子10)结果字节串。
- 仅从
INDEX
(在本例中为4)到TAG + 1
(11),即包含(10)的TAG
环,实际上在标签结束后一个字符。
因此,变量t
将在循环中得到值4..5..6..7..8..9..10。
实际上,这将数据从binary
中的位置4-10复制到resultsTag
中的位置4-10。
最后一部分是它不打印的原因(但这不是您代码中的唯一问题)。这个循环之后,存储器,开始在那里resultsTag
位于看起来就像这样:
__________ << defined size
????YYYYYYZ
^ ^ ^
| | \this is actually written outside of the allocated block of memory
| \this are the 6 characters of the tag you copied
\you never wrote to this part, so nobody knows what is there
继早先我的假设,您正在使用malloc
分配内存是隐含由系统以0字节(再次,什么是你应该依靠),很可能,它实际上是这样的:
当您尝试打印
resultsTag
__________ << defined size
0000YYYYYYZ
^ ^ ^
| | \this is actually written outside of the allocated block of memory
| \this are the 6 characters of the tag you copied
\zero values - remember that they act as string terminator!
所以会发生什么?系统会查看内存并说:好的,让我们打印一下。第一个角色是什么? ...哦,一个字符串终结者已经?那很简单!没什么可打印的!晚安。
所以没有打印出来,因为你的字符串以红色标志开头,说“字符串在这里结束”。 :P
因此,这最后一部分有三个问题:
- 你分配的内存量错了,并开始写的它,而不是从一开始就中间。
- 你写的超出了它的结尾(因为循环中的
TAG + 1
)。
- 您再次不要终止字符串。
让我解决它:
resultsTag = (char *)malloc(sizeof(char) * (TAG - INDEX + 1));
for(t = INDEX; t < TAG; t++){
resultsTag[t - INDEX] = binary[t];
printf("resultsTag[i] %c\n", resultsTag[t - INDEX]);
}
resultsTag[TAG] = 0; // string terminator
为了完整起见,在这里是做什么的:
- 分配内存标签的长度只(不索引加标签) ,加上1个字节的字符串终止符。在我的例子中,它将是6 + 1 = 7个字节。
- 从
INDEX
(4在我的例子),以TAG
(10)循环完全,即包括性TAG - 1
(9),但我们没有使用相同的指数复制的源和目标: 变量t
将得到值4..5..6..7..8 ..9,但目标索引将从0开始,而不是4,并且将通过0..1..2..3..4..5。
实际上,这将数据从binary
中的4-9位的数据复制到resultsTag
中的位置0-5。
所以,resultsTag
看起来就像这样:
_______ << defined size
YYYYYY0
它可能会少一点混乱,如果TAG
没有定义为“索引加上标签的长度的长度”,但只是作为长度标签的,因为这样的计算是更简单,更明显,但我会离开,作为一个练习;)
我可以看到其他一些问题与您的代码太:
1)您正在泄漏内存,因为resultsIndex
未被释放(即,你完成使用后,如果你真的只想得到标签(因为功能名称getTag
建议),你根本不需要整个部分resultsIndex
,虽然...我不知道你在返回后的值为resultsTag
它,但你必须确保调用者也可以释放它!
2)实际上,binary
闻起来像是另一个内存泄漏。 hex2bin
如何为返回的字符串分配内存?如果它也只是malloc
,并且没有魔法内存管理,那么最终还需要使用free(binary);
。
3)i = 0;
是超级的,因为您将它设置为零以下两行。
这可能是因为没有空字符。尝试添加resultsTag [t] = 0;在循环块的末尾。 – niyasc
尝试在循环后添加'resultsTag [t] ='\ 0';'。 – Chirality
@niyasc:缺少的终止符可能会导致在字符串后面打印垃圾*,而不会打印任何内容。在这种情况下,这是字符串开始处的“垃圾”问题。 – Clifford