我正在尝试重新分配拥有一些数据的char ptr。重新分配到大于当前的大小后,部分数据将被覆盖。
代码的相关部分如下:
char *convertToBinary(char *src, int *fractionPosition, bool double_precision) {
char *res = (char*)malloc(sizeof(char));
int currentResultPos = 0, precision;
int power = (strlen(src) - ((*fractionPosition) + 1)) * (-1);
float decimalValue_i = convertToInt(src, 10, 0, (*fractionPosition) - 1, 0);
float decimalValue_f = convertToInt(src, 10, (*fractionPosition) + 1,
strlen(src) - 1, power);
precision = determinePrecision(double_precision);
res = fromDecimalToDstinationBase(res, ¤tResultPos, 2,
decimalValue_i, &firstBinaryDigit);
res = convertFractionIntoResult(res, currentResultPos, 2,
decimalValue_f, precision);
*fractionPosition = currentResultPos - 1;
return res;
}
char *fromDecimalToDstinationBase(char *res, int *resPos, unsigned int dstB,
int decimalValue, char *firstDigit) {
int valueLength, sum = 0, power = 0;
while (decimalValue != 0) {
sum += (decimalValue % dstB) * pow(10, power++);
decimalValue /= dstB;
}
valueLength = countDecimalDigits(sum);
res = copyIntToStr(res, sum, resPos, valueLength);
return res;
}
char *copyIntToStr(char* res, int sum, int *resPos, int power) {
int remainder;
bool flag = true;
res = (char*)calloc(power + (*resPos) + 1, sizeof(char));
power--;
while (sum != 0) {
if (res[0] == '1' && flag) {
addFractionPoint(res, resPos);
flag = false;
}
remainder = sum % (int)pow(10, power);
res[(*resPos)++] = (sum / pow(10, power--)) + '0';;
sum = remainder;
}
res[*resPos] = '\0';
return res;
}
char *convertFractionIntoResult(char *res, int logicalS, unsigned int dstB,
float decimalValue, unsigned int precision) {
//here, logicalS = 5
int physicalS = logicalS, resRemainderCounter = 0;
float remainder = decimalValue;
// here, res = "1.101"
while (resRemainderCounter != precision) {
if (physicalS == logicalS) {
physicalS *= 2;
res = (char*)realloc(res, physicalS * sizeof(char));
// now, res = "1.1ÍÍÍÍÍÍÍýýýý"
}
我全神贯注地寻找解释。有谁知道为什么会这样?我可能做错了什么?
修改
另外,我试图用一些随机的非常大的数字替换物理,并且它没有改变任何东西。
答案 0 :(得分:2)
看起来你正在使用微软的编译器和库。在调试模式下,库会使用各种值来填充未初始化的内存部分,这些值在调试时会突出显示,以帮助您检测错误。
您看到的Í
对应于0xCD,这是库用于标记堆内存的未初始化部分的值。 ý
对应于0xFD,库用于标记堆分配末尾之外的区域。维基百科可以告诉你很多关于这些magic numbers的内容。
让我们来看看你的代码:
// here, res = "1.101"
// ...
physicalS *= 2;
res = (char*)realloc(res, physicalS * sizeof(char));
// now, res = "1.1ÍÍÍÍÍÍÍýýýý"
如果可以,realloc
应该返回至少所请求大小的缓冲区。它可以是原始缓冲区,扩展,也可以是新缓冲区。如果它是新缓冲区,并且新缓冲区大于原始缓冲区,则应将原始内容复制到新缓冲区。该库的调试版本将使用0xCD填充新缓冲区的其余部分。
因此,这个结果告诉我,当您认为res
指向"1.101"
时,它实际指向包含1.1
的未终止缓冲区,恰好跟随01
可能是缓冲区溢出的结果。
然后你要求一个更大的缓冲区,1.1
被忠实地复制到开头,然后调试库用0xCD字节填充新缓冲区的剩余部分,以表明它是未初始化的堆内存。 / p>
在这种情况下,我会使用调试器来监视每个malloc和realloc的实际缓冲区大小,并检查代码是否实际覆盖了缓冲区的末尾。
答案 1 :(得分:-1)
发现错误!
当调用addFractionPoint(res, resPos)
时,已经进行了另一次重新分配,这比在该呼叫之前进行的重新分配要小。
感谢大家的评论。