Program using malloc twice

Asked

Viewed 211 times

3

Why this program that divides a number into decimal notation, transforms it into binary notation and prints the number on the screen in the correct sequence (from bit most significant for the least significant) uses malloc twice?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    // Stack
    int decimal, q, r;
    int counter, i;
    char *binary = NULL;
    char *aux;

    printf("Digite um número em base decimal: ");
    scanf("%d", &decimal);

    counter = 1;
    while (decimal >= 2) {
        q = decimal / 2;
        r = decimal - (q * 2);

        // Heap
        aux = (char *) malloc(counter * sizeof(char));
        if (binary != NULL) {
            memcpy(aux, binary, counter-1);
            free(binary);
        }
        binary = aux;

        if (r == 0) {
            binary[counter-1] = 48; //'0';
        } else {
            binary[counter-1] = 49; //'1';
        }

        //printf("resto %d = %d\n", counter, r);
        counter++;
        decimal = q;
    }
    //printf("ultimo quociente = %d\n", q);

    // Heap
    aux = (char *) malloc(counter * sizeof(char));
    if (binary != NULL) {
        memcpy(aux, binary, counter-1);
        free(binary);
    }
    binary = aux;

    if (decimal == 0) {
        binary[counter-1] = 48; //'0';
    } else {
        binary[counter-1] = 49; //'1';
    }

    printf("Resultado em binário = ");
    for (i = counter-1; i >= 0; i--) {
        printf("%c", binary[i]);
    }
    printf("\n");

    free(binary);

    return 0;
}
  • I haven’t looked deeply but is there any reason to allocate dynamic memory? Actually the algorithm is very confusing. You probably don’t need to do so much. Did you? Do you have any requirement to do so?

  • It’s a code that my teacher asked me to analyze and I’m doubtful about that part, the idea was to use all this code to research about everything

  • Take a look at [tour]. You can accept an answer if it solved your problem. You can vote on every post on the site as well. Did any help you more? You need something to be improved?

3 answers

2

If the problem is to avoid doing any calculation of one of the leftovers again after the loop ends, it is easy to solve. The problem is that it is stopping when it arrives at the rest 2 and correct is to make the rest 1. So a simple change in the condition of the while fix this.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
    int decimal;
    printf("Digite um número em base decimal: ");
    scanf("%d", &decimal);
    int counter = 1;
    char *binary = NULL;
    while (decimal >= 1) {
        int q = decimal / 2;
        int r = decimal - (q * 2);
        char *aux = malloc(counter);
        if (binary != NULL) {
            memcpy(aux, binary, counter - 1);
            free(binary);
        }
        binary = aux;
        if (r == 0) binary[counter-1] = '0';
        else binary[counter-1] = '1';
        counter++;
        decimal = q;
    }
    printf("Resultado em binário = ");
    for (int i = counter - 1; i >= 0; i--) printf("%c", binary[i]);
    printf("\n");
    free(binary);
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

I haven’t looked at other aspects.

1

why this program [...] uses malloc twice?

For numbers with N bits, the cycle while of the program runs N - 1 time. This cycle is not executed when decimal for 0 or 1.

while (decimal >= 2) { /* ... */ }

Therefore, within the cycle, the allocation made is not sufficient to hold the full binary representation.

So at the end of the cycle, the program makes one more allocation for the last bit.

1

This exercise they put you in is interesting: understanding other people’s code and eventually modify it. The enunciation code has the virtue of: introducing several concepts (memory types, mallocs, memcpy, etc.) and still have "better things"

In addition to your question, if it were me (keeping the spirit of it) beyond the above mentioned improvements,

(1) ended dynamic memory

   char binary[32];

or at least allocated everything at once (required size=1+log2(decimal):

   binary=malloc((int)(1+log2(decimal)))

(2) replaces the

   if (r == 0) {
        binary[counter-1] = 48; //'0';
    } else {
        binary[counter-1] = 49; //'1';
    }

for

    binary[counter-1] = r + '0';

in short...

...
#include <math.h>

int main() {
    int decimal, q, r, counter;
    char *binary;

    printf("Digite um número em base decimal: ");
    scanf("%d", &decimal);
    binary=malloc((int)(1+log2(decimal)));

    counter = 0;               //from @pmg
    while (decimal > 0) {      //from @Maniero
        q = decimal / 2;
        r = decimal % 2;
        binary[counter] = r + '0';
        counter++;
        decimal = q;
    }

    printf("Resultado em binário = ");
    while (counter--) { putchar(binary[counter]); }
    printf("\n");

    free(binary);
    return 0;
}
  • 1

    It was nice to have a function decToBin :)

  • 2

    another suggestion ... start counting on 0 ... counter = 0; and stop using the counter - 1, using only counter.

  • @pmg, Certissimo! I’ll enter; (we’ll soon run out of code :)

  • @pmg, the braces are because if a swears I did to see if I hit the awk and perl code. And I’ll be good: nay I’ll put decimal /= 2... :)

  • 1

    @Jorgeb. yes! or at least one printf("%b",decimal)...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.