After a long time I’m playing with dynamic memory allocation in C and I’m encountering some issues with memory leaks … I just can’t see where the problem might be. Can Anyone help please?
EDIT2:
The program now works fine even with very large numbers and is quite quick 🙂 I decided to change the program structure and used struct instead of just char string. There should not be any memory leaks (tested with valgrind).
Current code:
#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;
}
You have an off-by-one error in your
sizeandindexrelationship:If, on entering the last iteration,
index == size-1, you are writing outside the allocated memory. Sometimes that can be harmless, for others you may overwrite some important data without causing an immediate crash, and sometimes it can cause an immediate crash (when the out-of-bounds access crosses a page boundary, usually). Change the test tosize - 1 <= index.In
get_number, if you need torealloc, you only change the local copy of thechar*to the input buffer, so if the location changes, the pointer inmainpoints to invalid memory. It should beand be called
get_number(&bin1);inmain.