为什么当我在其之前/之后使用 printf() 时,“malloc():损坏的顶部大小”错误会得到修复?

Ome*_*rFY 5 c malloc pointers

给定一个绝对路径,我试图获取某个目录之后的部分。getTargetPath函数执行此操作,当我编译并运行下面的代码时,该代码给出了预期的输出。

问题是当我删除mainprintf("\n")行之前的内容时malloc,我得到:

malloc():损坏的顶部大小
已中止(核心已转储)

因此,当我在代码行printf("\n")之前或之后放置malloc一个代码似乎工作正常,但当我删除它时,我收到上面的错误。

我的问题是,为什么会发生这种情况?我并不是要求解决路径字符串的问题。我只是想了解导致这种行为的原因。

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


const char* getTargetPath(const char* source)
{
    int count = 0;
    int i = 0;

    while(*source)
    {
        if (*source == '/')
        {
            ++count;
            if (count == 4)
            {
                break;
            }
        }
        ++source;
    }

    return source;
}


int main()
{
    const char* backup_path = "/home/ofy/real_2";
    char temp1[] = "/home/dir1/dir2/dir3/dir4/dir5";
    const char* s1 = temp1;

    const char* s2 = getTargetPath(s1);

    printf("\n");
    char* full_path = (char*)malloc(strlen(backup_path) * sizeof(char));

    strcpy(full_path, backup_path);
    strcat(full_path, s2);

    printf("%s\n", full_path);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

dbu*_*ush 4

您没有分配足够的空间full_path

char* full_path = (char*)malloc(strlen(backup_path) * sizeof(char));
Run Code Online (Sandbox Code Playgroud)

它需要至少与backup_path s2一样长,加上 1 作为终止空字节,但只够backup_path。这会导致您写入超过已分配内存的末尾,从而调用未定义的行为

由于未定义的行为,您无法预测程序将做什么。它可能会崩溃,可能会输出奇怪的结果,或者可能看起来工作正常。此外,进行看似无关的代码更改可能会改变 UB 的表现方式。这正是您删除通话时看到的内容printf。使用该printf程序“工作”,而没有它该程序崩溃。

要分配适当的空间量:

char* full_path = (char*)malloc(strlen(backup_path) + strlen(s2) + 1);
Run Code Online (Sandbox Code Playgroud)