char* init_array()
{
const int size = 5;
char *p = (char*) malloc(size * sizeof(char));
strcpy(p, "Hello, world! How are you?");
return p;
}
如果size = 5, malloc应该从内存中获得5个空闲字符,但是给定的字符串不适合5个字符,但是它可以工作。
我的问题是为什么?首先,我认为结果会被截断,但p是完整的字符串,而不仅仅是"Hello"或"Hell "我在Linux上使用GCC。它是与编译器有关还是标准的东西?
这被称为未定义行为,因为它是未定义的,有时它工作。是的,你可以在c语言中写过内存块,但这是非法的,因为它调用了未定义的行为,因此这种行为是不可预测的,你的程序可能会或可能不会工作。
你对strcpy()
的期望不会发生,因为strcpy()
在' '
终止字节之前复制了尽可能多的字符,它不在乎目标缓冲区是否足够大,这是你必须负责的事情。
如果你想复制一个精确的字节数(假设是5),你可以使用
memcpy(p, "Hello, this string is very large but it doesn't matter", 5);
,但注意p
之后不是一个有效的字符串,因为它没有终止' '
。
你也有另外两个常见的坏习惯,新的c程序员做
不需要强制转换
malloc()
的返回值你不需要使用
sizeof(char)
,因为它的定义是1
p = malloc(size);
应该足以为size - 1
字符串分配空间。
您正在经历的是缓冲区溢出
简而言之,你写入无效的内存地址调用未定义行为。一切皆有可能
它似乎工作,但实际上你的代码调用未定义的行为。您正在将数据写入未分配的内存位置。
你应该注意在
中strcpy(str1, str2);
strcpy
没有办法检查str2
指向的字符串是否适合str1
字符数组。在您的示例中,它将继续从"Hello, world! How are you?
复制字符到p
指向的数组。