内存重新分配期间缓冲区溢出

时间:2017-01-13 20:41:54

标签: c dynamic-arrays realloc buffer-overflow

我正在制作一个C程序,将12小时时钟转换为24小时制,输入格式为HH:MM:SSAM或HH:MM:SSPM和24小时时钟输出为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;
}

没有编译错误,但程序因缓冲区溢出而无法运行。当我减小dnamic数组time的大小时,是否有必要删除time的最后2个元素?

编辑:我为time终结器更新了strmilstrNULL,解决了缓冲区溢出问题。感谢您的推荐阅读!

1 个答案:

答案 0 :(得分:3)

  

编辑:我更新了时间,str和milstr为NULL终止符,并解决了缓冲区溢出问题。感谢您的推荐阅读!

你还有问题。

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

malloc分配11个字节,但scanf需要 12 。那是因为C字符串以空字节结束,所以总是需要再分配一个字节。

对于您正在进行的所有重新分配,您似乎正在这样做以截断字符串。对于3个字节来说这太过分了,无论如何它都不会被截断。因为realloc可能返回相同的指针,所以您不能指望收缩会使以下内存归零并截断字符串。当它返回不同的指针时,或者当它增长内存时,你不能指望它。只有calloc才能确定已分配的内存已归零。

相反,跳过realloc并粘贴一个空字节以截断字符串。

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

time仍然是12个字节(一旦malloc被修复),但空字节告诉C停止在time[8]读取。