使用strncpy时堆栈和堆的奇怪行为

win*_*und 4 c string heap stack

我发现了一个非常有趣的问题.

当我使用以下代码时:

int main() {
    char * in = "hi, ";
    char str[10];
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的结果是什么,printf没有用.

但如果我用这个:

int main() {
    char * in = "hi, ";
    char * str = malloc(sizeof(char) * 10) ;
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我能得到我的期望.

为什么会这样?是因为堆栈和堆?究竟是如何产生这种巨大差异的呢?

pb2*_*b2q 6

问题 - 在这两种情况下 - 都是在你打电话后你的字符串无法正常终止strncpy.

您指定2复制字符,并且源字符串in的长度为4.因此strncpy将复制2个字符,因为这小于源字符串的长度,所以不会添加空终止符 - 要理解为什么会这样,请查看strncpy文档:

If count is reached before the entire string src was copied, the resulting character array is not null-terminated.

在这种情况下,你会想要:

str[2] = '\0';
Run Code Online (Sandbox Code Playgroud)

在'strncpy'之后.

第二种情况似乎有效,因为您获得的缓冲区malloc恰好被初始化为全零,但您不应该依赖于此.

请查看strncpy文档,注意null终止的异常,一般情况下,请注意字符串终止!

有关更多详细信息,请参阅:为什么C++中的字符串通常以'\ 0'结尾?


P.P*_*.P. 5

代码编译得很好.运行时错误可能是因为,您没有终止strwith null.

从手册页:

strncpy()函数类似,只是复制了最多n个字节的src.警告:如果src的前n个字节中没有空字节,则dest中的字符串将不会以空值终止.

str[2]=0;之后添加strncpy().