1

I was trying to convert a decimal from [0, 255] to a 8 bit binary number, where each bit will be separated by a comma and a space. I tried the following (eventually it worked, except for the last bit does not require any separator ):

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

char* atobin(int input) {
    char *str = malloc(0);
    int index, count = 0;
    if (input > 255| input < 0) {
        printf ("Input out of range. Abort.\n");
        exit(EXIT_FAILURE);
    }

    for (index = 7; index >= 0; index--) {
        *(str + (count++)) = (input >> index & 1) ? '1' : '0';
        *(str + (count++)) = ',';
        *(str + (count++)) = ' ';
    }
    *(str + count) = '\0';
    return str;
}

int main(int argc, char *argv[]) {
    printf("%s\n", atobin(atoi(argv[1])));
    return EXIT_SUCCESS;
}

Now I have a few questions:

  1. I used malloc(0); as far as I am concerned, it will allocate no memory from the heap. So, how/ why is it working?
  2. Is the declaration *(str + count) = '\0'; necessary?
  3. Is there any way to optimize this code?

UPDATE

To carry on this experiment, I have taken the atobin function in to a .h file. This time it creates some problems. Now I add my last question:

What should be minimum integer to be used for the parameter of malloc? Some trial-and-error method makes me guess it should me 512. Any idea?

hola
  • 930
  • 1
  • 17
  • 35
  • Do you know "undefined behavior" concept in C/C++? – Grijesh Chauhan Apr 17 '14 at 18:37
  • @GrijeshChauhan No. :-( – hola Apr 17 '14 at 18:38
  • 1
    See `str = malloc(0)` is almost same as `str = NULL`, by doing `*(str + (count++)) = ',';` you are accessing/assigning to allocate memory that is illegal memory instruction. According to C standards the behaviour of your code is undefined. That means you may behavior unexpectedly at different execution instance. [Read](http://en.wikipedia.org/wiki/Undefined_behavior) – Grijesh Chauhan Apr 17 '14 at 18:41
  • Sorry typos in my above comment I mean "that `your code` may behavior unexpectedly at different execution instance" --- Also read [what's the point in `malloc(0)`?](http://stackoverflow.com/questions/2022335/whats-the-point-in-malloc0) – Grijesh Chauhan Apr 17 '14 at 18:46
  • @GrijeshChauhan OK, based on your discussions, it is (almost) clear now. – hola Apr 17 '14 at 18:58
  • That is good I believe this two Q&As will further help you **1.** http://stackoverflow.com/questions/671703/array-index-out-of-bound-in-c **2.** http://stackoverflow.com/questions/15646973/how-dangerous-is-it-to-access-an-array-out-of-bounds – Grijesh Chauhan Apr 17 '14 at 19:01
  • minimum integer as parameter? 0 `malloc(0)` is valid. accessing memory using returned pointer is not defined – LearningC Apr 17 '14 at 19:03
  • @LearningC I mean the minimum *safe* integer, in which case the successful execution will not depend on luck. – hola Apr 17 '14 at 19:06
  • 1
    ok. it depends on what amount of memory you need. it can be 1 byte for a character or more as you require. for your program its possibly 24 bytes if you dont use `,` at the end – LearningC Apr 17 '14 at 19:10
  • After update: how did you arrive at "512"? As @LearningC says, "24 bytes ought to be enough for everybody". – Jongware Apr 17 '14 at 20:37
  • 1
    Optimizing idea: `static char str[] = "0, 0, 0, 0, 0, 0, 0, 0";` Then just set the `str[0]`, `str[3]`, ... – chux - Reinstate Monica Apr 18 '14 at 05:36
  • @Jongware I don't know; when I try to use to from a separate `.h` file, it causes some errors (it shows memory dump etc.). Then I tried to change the `malloc` parameter, and after some experiments I noticed that `512` is stable (no problem created so far) - but even with `500`, there is some problems. I don't know what does it mean or why it is happening! – hola Apr 18 '14 at 05:48

2 Answers2

2
  1. From a malloc doc:

If size is zero, the return value depends on the particular library implementation (it may or may not be a null pointer), but the returned pointer shall not be dereferenced.

That it works for you is just luck. Try some random malloc and free afterwards and you will have a high probability - but no guarantee - that you will get a crash.

  1. This null-terminates the string. Depends on how you want to use the string if you need it. The printf in your example needs it, because that's the only way for it to know when the string ends.

  2. I'm sorry, I don't have time to take a closer look.

typ1232
  • 5,535
  • 6
  • 35
  • 51
2

malloc(0) is valid to be used. what it returns is implementation defined. but what happens if you access a object through the pointer returned by malloc(0) is undefined behavoiur. you can read this related question.
In C since strings are character arrays terminated by \0 it is better to use *(str + count) = '\0'; statement to set the last character of string. It is working in this code but its better to set the end of string in code always. It may work if bits are set to 0 since it is same as terminating a string.

Community
  • 1
  • 1
LearningC
  • 3,182
  • 1
  • 12
  • 19