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

使用strncpy时堆栈和堆的奇怪行为,c,string,stack,heap,C,String,Stack,Heap,我发现了一个非常有趣的问题 当我使用以下代码时: int main() { char * in = "hi, "; char str[10]; strncpy(str, in, 2); printf("output = %s", str); return 0; } 我的结果是没有结果,printf不起作用 但如果我用这个: int main() { char * in = "hi, "; char * str = malloc(sizeo

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

当我使用以下代码时:

int main() {
    char * in = "hi, ";
    char str[10];
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}
我的结果是没有结果,
printf
不起作用

但如果我用这个:

int main() {
    char * in = "hi, ";
    char * str = malloc(sizeof(char) * 10) ;
    strncpy(str, in, 2);
    printf("output = %s", str);
    return 0;
}
我能得到我所期望的


为什么会发生这种情况?是因为堆栈和堆吗?这到底是如何造成如此巨大的差异的?

在这两种情况下,问题是在调用
strncpy
后,字符串不会正确终止

您指定复制
2个
字符,并且中的源字符串
的长度为4。因此,
strncpy
将复制2个字符,由于小于源字符串的长度,因此不会添加空终止符-要了解原因,请查看:

如果在复制整个字符串src之前达到计数,则生成的字符数组不会以null结尾。

在这种情况下,您需要:

str[2] = '\0';
在'strncpy'之后

第二种情况可能似乎起作用,因为从
malloc
获得的缓冲区恰好被初始化为全零,但不应依赖于此

请查看,注意空终止的例外情况,通常,请小心字符串终止


有关更多详细信息,请参见:

代码编译良好。运行时错误可能是因为您没有使用null终止
str

从手册页:

strncpy()函数与之类似,只是 src被复制。警告:如果前n个字节中没有空字节 字节,放置在dest中的字符串将 不能以null结尾


添加
str[2]=0
strncpy()

之后,可以用零初始化内存,使其处于“安全”端

看看下面的代码

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

int main() {
    char * in = "hi, ";
    char * str = calloc(10,sizeof(char));
    strncpy(str, in, 2);
    printf("output = %s", str);
    free(str);      //<<Important step
    return 0;
}
intmain(){
char*in=“嗨,”;
char str[10]={0};
strncpy(str,in,2);
printf(“输出=%s”,str);
返回0;
}
int main(){
char*in=“嗨,”;
char*str=calloc(10,sizeof(char));
strncpy(str,in,2);
printf(“输出=%s”,str);

免费(str);//你遇到了什么编译器错误?代码似乎正确。这段代码编译得很好。你确定你没有犯其他错误吗?我过去经常做编译,结果显示无法编译。我仍然有点困惑,我的计算机没有gcc编译器。任何人都可以帮我编译或帮助我。谢谢太多了。哦,我的错。我使用堆栈的方式会导致什么都没有结果。printf语句没有workman 3 strncpy…顺便说一句:很少有情况需要strncpy()。这不是其中之一。我想他会想要str[2]=0,而不是str[3]=0好吧,它仍然像以前一样,它符合要求,但没有结果。我得到的结果是:它可以工作,但无法打印任何内容。但这是怎么回事???它应该是
str[2]=0;
str[2]='\0';
双引号表示字符串文字。非常感谢。我犯了这么多错误。我应该删除这篇文章吗?我修正了。谢谢你的帮助,事实上,我最大的错误是我在第二版中使用了双引号而不是单引号。我犯的愚蠢错误导致了这个XD