此代码中的内存错误在哪里?

问题描述:

有人问我用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, '\0', 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的高级功能或细微差别不甚了解。

最后,我会非常乐意提供关于如何提高此代码的整体有效性和可读性的任何意见。

+0

“巨​​大的错误”实际上并不是非常具体(甚至没有客观),所以你应该问那个人他们认为你的代码有问题。我唯一能看到的就是通过查看它而困扰我的是,你不检查'calloc'是否确实成功了。 – UnholySheep 2014-10-20 19:15:44

+0

感谢您的输入。我开始认为他们可能犯了一个错误。另外,我从关注中感觉到这不是一个很好的问题(哈!)。我应该在codereview上发布这个吗? – 2014-10-20 19:33:13

+0

您是否真的尝试过运行代码以查看会发生什么? – dbc 2014-10-20 19:34:51

如果要说一个“巨大的错误”,那么这个错误就是糟糕的代码本身。:)所以如果还有其他错误,那么实际上他们不值得讨论,直到代码被重写。

例如,你知道,如果一些整数为负,那么这样的

number = - number; 

语句后数可以像以前那样消极?:)

我认为“某人”的意思“巨大的错误”,你的字符串没有被零分。:)考虑一种情况,数字只有一个数字,buffer_size等于1

为什么buffer_size的类型是int而不是size_t?

同样在我看来,为这样的转换分配额外的缓冲区是一个坏主意。