为什么这个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 = '\0')
for (; n > 0 ; ++destStr)
*destStr = '\0';
*destStr = *strToCopy;
strToCopy++;
destStr++;
n--;
//stops copying when reaches [dest] end (overflow protection)
if (*destStr == '\0')
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: ZZZZZ\n");
st3 = strncpy(st1, st3, 0);
printf("%s\n", st3);
printf("Should be: ABZZZZZ\n");
st3 = strncpy(st1, st3, 2);
printf("%s\n", st3);
printf("Should be: ABCZZZZZ\n");
st3 = strncpy(st1, st3, 3);
printf("%s\n", st3);
printf("Should be: ABC\n");
st3 = strncpy(st1, st3, 4);
printf("%s\n", st3);
printf("Should be: AB\n");
st2 = strncpy(st1, st2, 2);
printf("%s\n", st2);
printf("Should be: AB\n");
st2 = strncpy(st1, st2, 4);
printf("%s\n", st2);
}
答案 0 :(得分:5)
您会收到细分错误,因为
char *st3 = "ZZZZZ";
目标是字符串文字。不得修改字符串文字,并且通常将它们存储在写保护的内存中。所以当你打电话时
strncpy(st1, st3, n);
使用n > 0
,您正在尝试修改字符串文字并导致崩溃(不一定,但通常)。
在复制循环中,您忘记取消引用strToCopy
if (strToCopy = '\0')
并写了=
而不是==
,因此strToCopy
设置为NULL
,导致strToCopy
的进一步解除引用以调用未定义的行为。
答案 1 :(得分:2)
我认为你不想要这个:
if (strToCopy = '\0')
相反,你可能想要做的是:
if (*strToCopy == '\0')
一般情况下,使用yoda conditions可以避免因比较与分配合并问题而头痛:
if ('\0' == *strToCopy)
答案 2 :(得分:0)
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 == '\0')
break; //exits loop
strToCopy++;
destStr++;
n--;
}
if (*destStr != '\0') *destStr = '\0';
主要:
printf("Should be: ZZZZZ\n");
st3 = strncpy(st1, st3, 0);
printf("%s\n", st3);
这是错误的,因为您要复制的长度为0
,因此您无法获得ZZZZZ