经过很长一段时间我在C中玩动态内存分配,我遇到了内存泄漏的一些问题......我只是看不出问题出在哪里。任何人都可以帮忙吗?
EDIT2: 程序现在工作正常,即使有非常大的数字,并且很快:)我决定改变程序结构并使用struct而不仅仅是char字符串。不应该有任何内存泄漏(使用valgrind测试)。
当前代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct binary{
char * number;
size_t length;
}Tbinary;
//exterminate leading zeros
size_t exterminate(char * bin, size_t length){
char * pch = NULL;
long position = 0;
pch = strchr(bin, '1');
if(pch==NULL){
bin[1] = '\0';
length = 2;
}
else{
position = pch-bin;
strcpy(bin, pch);
}
return (length-position);
}
int binaryAdd(Tbinary first, Tbinary second){
int a=0, b=0, sum=0, carry=0;
size_t index = first.length;
first.number[first.length] = '\0';
while((first.length != 0) || (carry != 0)){
if(first.length>1) a= first.number[first.length-2]-'0';
else a = 0;
if(second.length>1) b= second.number[second.length-2]-'0';
else b = 0;
sum = (a+b+carry)%2;
first.number[first.length-1] = (sum)+'0';
carry = (a+b+carry)/2;
if(first.length >0)first.length--;
if(second.length >0)second.length--;
}
exterminate(first.number,index);
printf("Sum: %s\n", first.number);
return EXIT_SUCCESS;
}
int get_number(Tbinary *bin_addr){
char * tmp, * bin;
char ch=1;
int size = 1, index = 0;
bin = bin_addr->number;
while(ch){
ch = getc(stdin);
if((ch == '\n') || (ch == ' ')) ch = '\0';
if((ch-'0' != 0) && (ch-'0' != 1) && (ch != '\0')) return EXIT_FAILURE;
if (size-1 <=index){
size += 5;
tmp = (char *)realloc(bin, size*sizeof(char));
if(tmp == NULL){
return EXIT_FAILURE;
}
bin = tmp;
bin_addr->number = bin;
}
bin[index++] = ch;
}
bin_addr->length = index;
bin_addr->length = exterminate(bin_addr->number, bin_addr->length);
return EXIT_SUCCESS;
}
int main (void)
{
Tbinary bin1 = {bin1.number = NULL, bin1.length = 0};
Tbinary bin2 = {bin2.number = NULL, bin2.length = 0};
//allocate space for first number
bin1.number = (char *)malloc(sizeof(char));
if(bin1.number == NULL)
return EXIT_FAILURE;
//allocate space for second number
bin2.number = (char *)malloc(sizeof(char));
if(bin2.number == NULL){
free(bin1.number);
return EXIT_FAILURE;
}
printf("Enter two binary numbers:\n");
//number1 load
if(get_number(&bin1) != EXIT_SUCCESS){
free(bin1.number);
free(bin2.number);
printf("Invalid input.\n");
return EXIT_FAILURE;
}
//number2 load
if(get_number(&bin2) != EXIT_SUCCESS){
free(bin1.number);
free(bin2.number);
printf("Invalid input.\n");
return EXIT_FAILURE;
}
//add the two numbers
if(bin1.length >= bin2.length){
if(binaryAdd(bin1, bin2) != EXIT_SUCCESS){
free(bin1.number);
free(bin2.number);
printf("Invalid input.\n");
return EXIT_FAILURE;
}
}
else{
if(binaryAdd(bin2, bin1) != EXIT_SUCCESS){
free(bin1.number);
free(bin2.number);
printf("Invalid input.\n");
return EXIT_FAILURE;
}
}
free(bin1.number);
free(bin2.number);
return EXIT_SUCCESS;
}
答案 0 :(得分:1)
在binaryAdd()中,你应该在realloc()之后在所有情况下释放sum,而不仅仅是当realloc()返回null时。 get_number()中的内容相同。
关于a = (int)strlen(first);
为什么要将strlen()的返回转换为int?
另外,不要强制转换分配函数。
答案 1 :(得分:0)
您的size
和index
关系中出现了一个错误:
if (size <=index){
size += 5;
tmp = (char *)realloc(sum, size*sizeof(char));
if(tmp == NULL){
free(sum); // free memory to avoid leak
return EXIT_FAILURE;
}
sum = tmp;
}
for(int i=index; i>0; i--){
sum[i] = sum[i-1];
}
sum[0] = num%2+'0';
carry = num/2;
index++;
}
sum[index] = '\0';
如果在进入最后一次迭代index == size-1
时,您正在写入已分配的内存之外。有时这可能是无害的,对于其他人,您可能会覆盖一些重要数据而不会立即崩溃,有时它可能导致立即崩溃(当越界访问跨越页面边界时,通常)。将测试更改为size - 1 <= index
。
在get_number
中,如果需要realloc
,则只需将char*
的本地副本更改为输入缓冲区,因此如果位置发生更改,则{{1}中的指针指向无效的内存。它应该是
main
并在int get_number(char **bin_addr){
char * tmp, bin = *bin_addr;
char ch=1;
size_t size = 1, index = 0;
while(ch){
ch = getc(stdin);
if((ch == '\n') || (ch == ' ')){
ch = '\0';
}
if((ch-'0' != 0) && (ch-'0' != 1) && (ch != '\0')){
return EXIT_FAILURE;
}
if (size-1 <=index){
size += 5;
tmp = (char *)realloc(bin, size*sizeof(char));
if(tmp == NULL){
return EXIT_FAILURE;
}
bin = tmp;
*bin_addr = bin; // let the pointer always point to the real block
}
bin[index++] = ch;
}
return EXIT_SUCCESS;
}
中调用get_number(&bin1);
。