超过24个字符后strncat或strndmp添加随机字符

问题描述:

我目前正在学习C,我决定做一个简单的函数来交换字符串的两半。我使用strndmp来获取字符串的一半,并使用strncat将另一半添加到strndmp结果的末尾。之后,我打印输出。该脚本输出了字符串,其中两半交换了,但最后几个字符被随机字符替换。我真的很困惑,因为如果我在打印交换字符串之前打印某些内容或输入的字符串未满24个字符,则不会发生这种情况。下面的代码:超过24个字符后strncat或strndmp添加随机字符

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

void halfSwap(char * sample); 
void halfSwap(char * sample){ 
    char * buff; 
    buff = strndup(sample+strlen(sample)/2,strlen(sample)); 
    strncat(buff,sample,strlen(sample)/2); 
    printf("Sample length: %d\n",strlen(sample)); 
    printf("Buffer output: %s\n",buff); 
} 
int main() { 
    //printf("Uncommenting this will remove the error\n\n"); 
    //Characters only go missing after sample exceeds 24 chars 
    halfSwap(" worrrrrrrlddhellllllllooo"); 
    //Error does not occur after printng once 
    halfSwap(" worrrrrrrlddhellllllllooo"); 
} 

,输出是:

Sample length: 26 
Buffer output: hellllllllooo worrrrrrrl 
Sample length: 26 
Buffer output: hellllllllooo worrrrrrrldd 

在此先感谢。

+0

你在'halfSwap()'每次你调用它泄漏内存。 –

+1

AFAICS,['strndup()']的规范(http://pubs.opengroup.org/onlinepubs/9699919799/functions/strndup.html)并不保证分配与第二个参数一样多的内存。如果输入比第二个参数短,它只能为输入分配足够的空间,包括空终止符。因此,追加到分配的空间是未定义的行为。如果您在可以运行[Valgrind](http://valgrind.org/)的平台上,请使用它。 –

+0

如果您通过调试代码(例如,通过* code-blocks *)来帮助自己,您可能会自己得到答案。此外,调试和检查变量和指针的值将帮助您更快地学习。 – ssd

对strndup的调用只为字符串的后半部分分配足够的内存,所以当你对它进行strncat时,它超出了为buff分配的空间,并且行为是未定义的。你可能想要的,而不是我们沿着这些线:

int len = strlen(sample); 
int half = len/2; 
buff = (char*)malloc(len+1); 
strcpy(buff,&sample[half]); 
strncat(buff,sample,half);