0

I was making a C program to convert 12 hour clock into 24 hour clock with the format of input being HH:MM:SSAM or HH:MM:SSPM and 24hr clock output being HH:MM:SS

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

int main(){
    char *time = malloc(11 * sizeof(char));
    scanf("%11s", time);
    if (time[8] == 'A' || time[8] == 'P')
    {

        if (time[8] == 'A')
        {
            time = realloc(time, (9 * sizeof(char)));                
            printf("%s\n", time);
        }
        else
        {
            time = realloc(time, (8 * sizeof(char)));                
            char str[3];
            sprintf(str, "%c%c", time[0], time[1]);
            int hours;
            hours = atoi(str);
            int milhours;
            milhours = hours + 12;
            char milstr[3];
            sprintf(milstr, "%d", milhours);
            time[0] = milstr[0];
            time[1] = milstr[1];
            printf("%s\n", time);
        }   
    }
    else
    {
        printf("give a standard format\n");
        return 0;
    }
    return 0;
}

There is no compilation error,but the program doesnt run because of buffer overflow. When I reduce the size of dnamic array time , is it necessary that the last 2 elements of time will be removed?

EDIT: I updated time, str and milstr for NULL terminator and the buffer overflow problem is resolved. Thanks for the recommended reading!

30
  • 4
    why would you call free(time) after realloc? Commented Jan 13, 2017 at 20:43
  • 4
    Allocate +1 for NUL terminator. Commented Jan 13, 2017 at 20:43
  • 2
    sizeof(char) equals 1 by definition. Commented Jan 13, 2017 at 20:45
  • 2
    time is a commonly used identifier, better use your own. Commented Jan 13, 2017 at 20:46
  • 3
    Editing your question in place is not a good idea after comments and/or questions have been given as such edits may render the answers/comment und-understandable. Better add edits as updates/additions to your question. Commented Jan 13, 2017 at 21:01

1 Answer 1

3

EDIT: I updated time, str and milstr for NULL terminator and the buffer overflow problem is resolved. Thanks for the recommended reading!

You still have problems.

char *time = malloc(11 * sizeof(char));
scanf("%11s", time);

That malloc allocates 11 bytes, but that scanf needs 12. That's because C strings are terminated with a null byte, you always need to allocate one more byte.


As for all the reallocating you're doing, it seems like you're doing that to truncate the string. That's overkill for 3 bytes, and it won't truncate anyway. Because realloc may return the same pointer, you can't expect that shrinking will zero the following memory and truncate the string. You can't expect it when it returns a different pointer either, or when it grows memory. Only with calloc can you be certain that the allocated memory has been zeroed.

Instead, skip the realloc and stick a null byte in to truncate the string.

if (time[8] == 'A')
{
    time[8] = '\0';
    puts(time);
}

time is still 12 bytes (once the malloc has been fixed), but the null byte tells C to stop reading at time[8].

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the answer! I found out these problems maybe at the same time you were, and I fixed those, my main issue was buffer overflow though which I got an idea through comments :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.