有人让我写这段代码作为C中的练习。当他们查看我写的内容时,他们立即告诉我在内存管理方面存在巨大错误。作为一个简单的练习,他们希望我找到并纠正这个错误。我的知识一定有差距,或者我一定忽略了一些非常明显的东西,因为我一辈子都找不到。如果有人能帮我弄清楚,我会非常感激。
这是代码:
char int_to_char(int number){
if (number > 9) return (char)(((int)'A') + number - 10);
else return (char)(((int)'0') + number);
}
int change_base(char* output, int buffer_size, int decimal_number, int base){
//check for valid parameters
if((base < 2) || (base > 26)) return -1; //range error
//ready variables
int output_i = 0;
int tmp_string_i = 0;
int dividend;
char remainder;
char * tmp_string = calloc(buffer_size, sizeof(char));
memset(output, ' ', buffer_size*sizeof(char));
//check for negative input
if(decimal_number < 0){
output[0] = '-';
dividend = -decimal_number;
output_i++;
}
else dividend = decimal_number;
//find digits
while(dividend / base != 0){
remainder = int_to_char(dividend % base);
dividend = dividend / base;
tmp_string[tmp_string_i] = remainder;
tmp_string_i++;
if(tmp_string_i + 1 > buffer_size){ //+1 for the extra negative sign
free(tmp_string);
return -2; //buffer size error
}
}
//add last digit to string
remainder = int_to_char(dividend);
tmp_string[tmp_string_i] = remainder;
//copy tmp_string to output in reverse order
for(; tmp_string_i >= 0; tmp_string_i--){
output[output_i] = tmp_string[tmp_string_i];
output_i++;
}
free(tmp_string);
return 0;
}
同样值得注意的是,我已经通过Valgrind运行了这段代码,以查找任何常见的内存错误,但它没有报告任何错误。我对Valgrind的高级功能或细微差别了解不多。
最后,我很乐意就如何提高代码的整体有效性和可读性发表任何意见。
如果说一个"巨大的错误",那么这个错误就是糟糕的代码本身。:)l因此,如果还有其他错误,那么事实上,在重写代码之前,它们不值得讨论。
例如,你知道吗,如果某个整数是负数,那么在像这样的语句之后
number = - number;
数字可以和以前一样为负数?:)
我认为"某人"指的是你的字符串不是零的"巨大错误"。:)考虑一种情况,当数字只有一位并且buffer_size等于1 时
为什么buffer_size的类型是int而不是size_t?
此外,在我看来,为这样的转换分配额外的缓冲区是个坏主意。