C语言 为什么这个 strncpy() 实现在第二次运行时崩溃



为什么这个strncpy()实现在第二次运行时崩溃,而第一次运行工作正常?

斯特内皮

从字符串复制字符 复制源的前n个字符 到目的地。如果源 C 字符串的末尾(这是信号 通过空字符)在复制n字符之前找到, 目标用零填充,直到总共 n 个字符 被写到它。

在以下情况下,不会在目标末尾隐式追加空字符 源比 n 长(因此,在这种情况下,目标可能不是 以空结尾的 C 字符串)。

char *strncpy(char *src, char *destStr, int n)
{
    char *save = destStr; //backing up the pointer to the first destStr char
    char *strToCopy = src; //keeps [src] unmodified
    while (n > 0)
    {
        //if [n] > [strToCopy] length (reaches [strToCopy] end),
        //adds n null-teminations to [destStr]
        if (strToCopy = '') 
            for (; n > 0 ; ++destStr)
                *destStr = '';
        *destStr = *strToCopy;
        strToCopy++;
        destStr++;
        n--;
        //stops copying when reaches [dest] end (overflow protection)
        if (*destStr == '')
            n = 0; //exits loop
    }
    return save;
}
/////////////////////////////////////////////
int main()
{
    char st1[] = "ABC";
    char *st2;
    char *st3 = "ZZZZZ";
    st2 = (char *)malloc(5 * sizeof(char));

    printf("Should be: ZZZZZn");
    st3 = strncpy(st1, st3, 0);
    printf("%sn", st3);
    printf("Should be: ABZZZZZn");
    st3 = strncpy(st1, st3, 2);
    printf("%sn", st3);
    printf("Should be: ABCZZZZZn");
    st3 = strncpy(st1, st3, 3);
    printf("%sn", st3);
    printf("Should be: ABCn");
    st3 = strncpy(st1, st3, 4);
    printf("%sn", st3);
    printf("Should be: ABn");
    st2 = strncpy(st1, st2, 2);
    printf("%sn", st2);
    printf("Should be: ABn");
    st2 = strncpy(st1, st2, 4);
    printf("%sn", st2);
}

你得到一个分段错误,因为

char *st3 = "ZZZZZ";

目标是字符串文本。字符串文本不得修改,并且它们通常存储在写保护内存中。所以当你打电话

strncpy(st1, st3, n);

使用 n > 0 ,您正在尝试修改字符串文字,这会导致崩溃(不一定,但通常)。

在复制循环中,您忘记取消引用strToCopy

if (strToCopy = '')

并且写=而不是==,所以strToCopy被设置为NULL,导致strToCopy进一步取消引用以调用未定义的行为。

我认为你不想要这个:

if (strToCopy = '') 

相反,您可能打算这样做:

if (*strToCopy == '') 

一般来说,使用尤达条件可以为您省去比较与分配合并问题的麻烦:

if ('' == *strToCopy)
while (n > 0)
    {
        //if [n] > [strToCopy] length (and reaches [strToCopy] end),
        //adds n null-teminations to [destStr]
        *destStr = *strToCopy;
        //stops copying when reaches [dest] end (overflow protection)
        if (*destStr == '')
            break; //exits loop
        strToCopy++;
        destStr++;
        n--;

    }
if (*destStr != '') *destStr = '';

主要:

printf("Should be: ZZZZZn");
    st3 = strncpy(st1, st3, 0);
    printf("%sn", st3);

这是错误的,因为您要复制的长度是0因此您不会获得ZZZZZ

相关内容

  • 没有找到相关文章

最新更新