FROM:http://codewenda.com/c语言结构体直接赋值/
在C语言中结构体变量之间可以进行赋值操作吗?
简单结构体的赋值
先说结论:一般来说,C语言中的结构体变量可以用另一个变量对其进行赋值或初始化。简单结构体(不包含指针成员)直接赋值没有问题。
我们先下面一段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <stdio.h> #include <stdlib.h> struct MyStruct { int a; int b; char c[10]; }; int main() { struct MyStruct t1 = {1, 2, "hello" }; struct MyStruct t2 = {3, 4, "world" }; t2 = t1; //将t1赋值给t2 printf ( "MyStruct t1: %d, %d, %s\n" , t1.a, t1.b, t1.c); printf ( "MyStruct t2: %d, %d, %s\n" , t2.a, t2.b, t2.c); return 0; } |
以上代码的输出为:
1 2 | MyStruct t1: 1, 2, hello MyStruct t2: 1, 2, hello |
以上用t1给t2进行初始化,结果也相同。可以看到简单的结构体(结构体的成员没有指针成员)变量之间直接赋值是没有问题的。
有指针成员的结构体赋值
而通常情况下,稍微复杂一点的结构体里面会有指针成员,那么以上的浅拷贝则会有问题了,我们假设MyStruct里面的成员c不是数组,而是字符指针,会有什么问题呢?
看如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <stdio.h> #include <stdlib.h> #include <string.h> struct MyStruct { int a; int b; char * c; }; int main() { struct MyStruct t1; t1.a = 1; t1.b = 2; // 为指针区域赋值 char *p = ( char *) malloc (10* sizeof ( char )); strcpy (p, "hello" ); t1.c = p; struct MyStruct t2; t2 = t1; printf ( "MyStruct t1: %d, %d, %s\n" , t1.a, t1.b, t1.c); // 释放了t1的内存 // free(p); printf ( "MyStruct t2: %d, %d, %s\n" , t2.a, t2.b, t2.c); printf ( "t1 pointer addr: %p\n" , t1.c); printf ( "t2 pointer addr: %p\n" , t2.c); return 0; } |
上面的输出结果为:
1 2 3 4 | MyStruct t1: 1, 2, hello MyStruct t2: 1, 2, hello t1 pointer addr: 0x6000284d0 t2 pointer addr: 0x6000284d0 |
可以看到,赋值会直接将t1的指针变量赋值给t2.c,如果我们在赋值之后将t1所用的资源释放掉,那么使用t2的话则可能导致内存泄漏了。如果上面的代码,我们没有注释掉 free(p);,那么输出t2时结果这不确定了:
1 2 3 4 | MyStruct t1: 1, 2, hello MyStruct t2: 1, 2, (/.? t1 pointer addr: 0x6000284d0 t2 pointer addr: 0x6000284d0 |
所以,如果struct中有指针成员,那么结构体赋值不能简单的直接复制了,而需要为指针成员另外分配内存,并将数据拷贝过去,当然我们可以将这些处理封装在单独的函数中来完成。
示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #include <stdio.h> #include <stdlib.h> #include <string.h> struct MyStruct { int a; int b; char * c; }; int main() { struct MyStruct t1; t1.a = 1; t1.b = 2; // 为指针区域赋值 char *p = ( char *) malloc (10* sizeof ( char )); strcpy (p, "hello" ); t1.c = p; struct MyStruct t2; // 各个成员分别赋值,可以进行封装 t2.a = t1.a; t2.b = t1.b; char *p2 = ( char *) malloc (10* sizeof ( char )); strcpy (p2, t1.c); t2.c = p2; printf ( "MyStruct t1: %d, %d, %s\n" , t1.a, t1.b, t1.c); // 释放了t1的内存 free (p); printf ( "MyStruct t2: %d, %d, %s\n" , t2.a, t2.b, t2.c); // 释放了t2的内存 free (p2); printf ( "t1 pointer addr: %p\n" , t1.c); printf ( "t2 pointer addr: %p\n" , t2.c); return 0; } |
以上代码输出结果为:
1 2 3 4 | MyStruct t1: 1, 2, hello MyStruct t2: 1, 2, hello t1 pointer addr: 0x6000284d0 t2 pointer addr: 0x600062e10 |