为何C++类中长度为1的char数组能输出完整长字符串?
为什么这段C++代码能输出完整字符串?
先看你给出的代码:
#include <iostream> #include <string.h> class Person { public: char m_Name[1]; }; int main() { const char* name = "Kim Na In"; Person* pPerson = (Person*)malloc(sizeof(Person) + strlen(name)); pPerson->m_Name[0] = '\0'; strcat(pPerson->m_Name, name); std::cout << pPerson->m_Name << std::endl; }
核心原因可以拆解成这几点:
足够的内存提前分配:代码里用
malloc申请了一块连续内存,大小是Person类的字节数(仅1字节,因为只有一个char[1]成员)加上字符串name的长度。这块内存完全能放下初始的'\0'、整个name字符串以及最终的终止符,所以后续的字符串操作不会越界到非法内存区域。数组名自动转为指针:当你使用
pPerson->m_Name时,这个长度为1的char数组名会隐式转换成指向数组第一个元素的char*指针。std::cout处理char*类型时,只会从指针指向的地址开始逐个输出字符,直到碰到'\0'终止符——它完全不关心你声明的数组长度是多少,只认内存里的实际内容。C风格字符串函数的工作逻辑:
strcat函数同样只认指针和终止符,它会从m_Name里的初始'\0'位置开始,把name的字符逐个拷贝到后续内存,最后再补一个'\0'。因为我们提前分配了足够的内存,所以这个操作在当前场景下是能正常执行的。
不过必须强调:这种写法是极不规范的C++代码,存在很多问题:
- 用
malloc分配类对象(哪怕是简单的POD类型)不符合C++的编程规范,应该使用new或更现代的内存管理方式。 - 依赖类的内存布局和数组隐式转指针的特性,代码可读性极差,后续维护极易出错。
- 代码没有释放
malloc申请的内存,会造成内存泄漏。
内容的提问来源于stack exchange,提问作者dongyeob
相关产品推荐
相关产品推荐

