我的strlen在2种不同的编译器中的工作方式不同,有什么解释吗?

时间:2019-04-17 06:44:35

标签: c malloc strlen

我使用的是我安装的gcc编译器,该编译器是从cmd(在编辑器可视代码中编写)运行的,并且为了调试,我还安装了Visual Studio。 这是我的第二学期,我刚刚了解了malloc / calloc等。

所以这行:

ch_pointer = (char *)malloc(length * sizeof(char));
当我使用strlen(ch_pointer)24作为答案时,我的gcc编译器中的

给出了回报。

如果我使用长度太大的数字(例如100),它也会显示strlen(ch_pointer) == 0

如果我在Visual Studio中将其编写为:

ch_pointer = (char *)malloc(((length + 1) * sizeof(char)) / 2 - 1);

这是唯一能完美工作的情况。

get_number()函数很好,只是确保您将输入一个int类型。

void main() {
    char *ch_pointer = '\0';
    int length = 0;
    printf("Please write down your sentence length in characters (including spaces): ");
    length = get_number();

    ch_pointer = (char *)malloc(((length + 1) * sizeof(char)) / 2 - 1); 
    ch_pointer[strlen(ch_pointer) - 1] = '\0';

    printf("Please write down your sentence: ");
    for (int filling = 0; filling < strlen(ch_pointer); filling++)
        scanf(" %c", &ch_pointer[filling]);
    for (int printing = 0; printing < strlen(ch_pointer); printing++)
        printf("%c", ch_pointer[printing]);

    free(ch_pointer);
}

如果我记下4甚至100以获得以5结尾的数组长度101'\0',两个编译器的工作原理相同&让我输入并完美打印:

length = 4
strlen(ch_pointer) == 4

length = 100
strlen(ch_pointer) == 100

2 个答案:

答案 0 :(得分:2)

这里有一个基本的误解:strlen对您传入的数组的分配大小一无所知;它会一直走直到找到空字符,然后返回必须跳过的字符数。

由于malloc返回指向未初始化内存的指针,其内容是不可预测的,因此对其调用strlen是未定义的行为-在最坏的情况下,如果内存块中没有零,它将甚至继续阅读它,希望会导致程序崩溃。

答案 1 :(得分:1)

问题是,malloc()返回一个指向分配的内存的指针,其内容是不确定的。

引用C11,第7.22.3.4章

  

malloc函数为size指定大小的对象分配空间。   值不确定。

也就是说,对于7.24.6.3章中的strlen()

  

strlen函数计算s指向的字符串的长度。

  

strlen函数返回终止null之前的字符数   字符。

因此,strlen()专家认为该参数是 string

现在,根据定义,由malloc()返回的指针所指向的内存不能保证在内存中的任何地方都存在空终止符。因此,您无法对此运行strlen()。您很可能会通过内存溢出来调用undefined behaviour