printf导致输出问题

时间:2013-12-11 16:10:40

标签: c string

我对以下C代码有点问题。如果我注释掉“ LINE 24 ”,那么我会得到以下输出:

aaaaaaaaaaaaaaaaaaaaaaaaa

如果我不评论,我会得到以下内容:

aaaaaaaaaaaaaaaaaaaaaaaaadƔ?LƔ?LƔF?W'F'W'F'W'F'W'F'W'F'W'F'W'


有人可以告诉我为什么吗?

我正在使用mac os x 10.5.4和gcc

void test(char* a , char* b);

int main()
{
    char * str = "aaaaaaaaaaaaaaaaaaaaaaaaa";
    char* str2 = malloc(4*sizeof(str));
    test(str , str2);
    return 0;
}

void test(char* a , char* b)
{
    int i = 0;
    printf("\n########\n");
    for( i = 0 ; i < strlen(a)  ; i++)
    {
        printf("%d" , i);   /******** LINE 24 ********/ 
        b[i] = a[i];        
    }

    printf("\n########\n");
    for( i = 0 ; i < strlen(b) ; i++)
    {
        printf("%c" ,*(b+i));
    }
    printf("\n########\n");

}



谢谢你的回复。

2 个答案:

答案 0 :(得分:1)

我在你的代码中看到两个问题:

首先分配str2

 char* str2 = malloc(4*sizeof(str));  // This will allocate 4 times the size of a char pointer. You cannot be sure that str will fit!

第二次将a复制到b。 您需要在b

的末尾添加字符串终止符
for( i = 0 ; i < strlen(a)  ; i++)
{
    printf("%d" , i);   /******** LINE 24 ********/ 
    b[i] = a[i];        
}
b[i] = '\0';   // Make sure b is properly terminated

答案 1 :(得分:1)

char * str = "aaaaaaaaaaaaaaaaaaaaaaaaa";
char* str2 = malloc(4*sizeof(str));

str是一个指针,其大小(大概)是32位 - &gt; 4字节。所以你分配的不是字符串的大小,而是指向字符串的四个指针的大小需要(16个字节),而你的字符串长度为26个字节(包括0个字节)。

在地址上,当您输出一个字符串时,您必须分配比长度多一个字节,以便考虑指示字符串结尾的0字节。

char * str = "aaaaaaaaaaaaaaaaaaaaaaaaa";
char* str2 = malloc(strlen(str)+1);

int i;
for( i = 0 ; i < strlen(a)  ; i++)
{
    printf("%d" , i);   /******** LINE 24 ********/ 
    b[i] = a[i];        
}
b[i] = 0; // Terminate the string.

如果你没有终止字符串,那么处理字符串的函数(如strlenprintf等)将扫描字符串,它们会遇到0字节,这可能是你记忆中的任何地方。因此,代码中的strlen有时似乎给出了正确的长度,如果这样的字节恰好在最后,但它会更频繁地给出错误的结果(未定义的行为),这会导致奇怪的字符你看到你的输出。