编程后端C开发者

描述C语言中结构体赋值操作的特点。结构体是如何复制的,有什么优缺点,可能出现什么错误?

用 Hintsage AI 助手通过面试

答案

C语言支持将一个相同类型的结构体直接赋值给另一个结构体:所有字段都是按字节复制(memcpy)。这对于快速克隆结构体很方便,例如:

struct Point { int x, y; }; struct Point p1 = {10, 20}; struct Point p2; p2 = p1; // 现在 p2.x=10, p2.y=20

特点:

  • 所有字段都按"原样"(逐位)复制。
  • 如果字段是指针/数组,则只复制指针本身,而不复制该地址的内容(不会进行深拷贝!)。
  • 赋值仅适用于相同类型的结构体。

具有误导性的问题

"如果结构体包含指向动态分配内存的指针,赋值一个结构体给另一个会发生什么?"

许多人认为会复制所有内容,但并非如此。

答案: 只复制指针的值(地址),而不是该地址中的数据。两个结构体对象将指向同一内存。

struct Data { int *arr; }; struct Data d1; d1.arr = malloc(10 * sizeof(int)); struct Data d2 = d1; // d2.arr == d1.arr

修改d2.arr时,您也在修改d1.arr所指向的内存。

由于对主题细节不了解而导致的实际错误示例


故事1

数据序列化:试图赋值一个具有内部缓冲区指针的结构体(malloc)——复制后两个不同的对象指向同一内存,并在释放时都调用了free()。结果——双重释放,服务崩溃。


故事2

在尝试克隆复杂结构体时,忘记对指针字段进行深拷贝。修改副本后期望独立性,但改变了原始结构(反之亦然),导致数据不一致。


故事3

存储了一个嵌套指向字符串的指针的结构体。赋值结构体后释放了其中一个字符串,导致另一个结构体突然"坏掉"(悬空指针),程序开始表现异常。