刚刚看代码看到一个地方用双指针作为函数参数,调用的地方需要取到有效值。我想也没想就修改了一下代码,结果运行后是错误的。
仔细想了想,觉得有必要捋一捋,就写了下面的测试代码作为小结。我错用了第一种错误的办法。
通过指针作为参数传值,出了传递入参外,通常也是为了能够通过这个指针返回结果。我的总结是这样的:
1. 如果是单指针,一般直接修改指针指向变量的值;
2. 如果是双指针,一般修改双指针指向指针的值,即赋一个有效的地址给这个指针。
所以要注意的是,这个地址指向的内存必须在被取值之前是有效的,如果是栈内存,出栈后就可能没用了;如果是堆内存,不能被释放;所以最好是全局或者静态内存。
代码:
1: #include "stdafx.h"
2: #include <stdio.h>
3: #include <stdlib.h>
4:
5: typedef struct {
6: int success;
7: char *finalResponse;
8: } ATResponse;
9: ATResponse *g_at = (ATResponse *)calloc(1, sizeof(ATResponse));
10:
11: void singleP(ATResponse *p)
12: {
13: printf("singleP: change variable from pointer.n");
14: p->success = 2;
15: p->finalResponse = "single_finalResponse";
16: }
17:
18: void doubleP(ATResponse **pp)
19: {
20: printf("doubleP: change pointer, use globe variable memory. n");
21:
22: g_at->success = 1;
23: g_at->finalResponse = "double_finalResponse";
24: *pp = g_at;
25: }
26:
27: void doubleP_1(ATResponse **pp)
28: {
29: static ATResponse at1;
30:
31: printf("doubleP_1: change pointer, use static variable memory. n");
32: at1.success = 1;
33: at1.finalResponse = "double_1_finalResponse";
34: *pp = &at1;
35: }
36:
37: void doubleP_err1(ATResponse **pp)
38: {
39: ATResponse at1;
40:
41: printf("doubleP_error1: the memory of at would be overlap some time. n");
42: at1.success = 1;
43: at1.finalResponse = "doubleP_err1";
44: *pp = &at1;
45: }
46:
47: void doubleP_err2(ATResponse **pp)
48: {
49: ATResponse *at1 = (ATResponse *)calloc(1, sizeof(ATResponse));
50:
51: printf("doubleP_error2: the memory could not be free which make memory leak. n");
52: at1->success = 1;
53: at1->finalResponse = "doubleP_err2";
54: *pp = at1;
55: }
56:
57: int _tmain(int argc, _TCHAR* argv[])
58: {
59: ATResponse at = {0, "ok"};
60: ATResponse *p = &at;
61:
62: printf("before: %d,%s n", p->success,p->finalResponse);
63: singleP(p);
64: printf("after: %d,%s n",p->success,p->finalResponse);
65:
66: printf("before: %d,%s n", p->success,p->finalResponse);
67: doubleP(&p);
68: printf("after: %d,%s n",p->success,p->finalResponse);
69:
70: printf("before: %d,%s n", p->success,p->finalResponse);
71: doubleP_1(&p);
72: printf("after: %d,%s n",p->success,p->finalResponse);
73:
74: printf("before: %d,%s n", p->success,p->finalResponse);
75: doubleP_err1(&p);
76: printf("after: %d,%s n",p->success,p->finalResponse);
77:
78: printf("before: %d,%s n", p->success,p->finalResponse);
79: doubleP_err2(&p);
80: printf("after: %d,%s n",p->success,p->finalResponse);
81:
82: scanf_s("press any key to exit");
83: free(g_at);
84: return 0;
85: }
输出:
before: 0,ok
singleP: change variable from pointer.
after: 2,single_finalResponse
before: 2,single_finalResponse
doubleP: change pointer, use globe variable memory.
after: 1,double_finalResponse
before: 1,double_finalResponse
doubleP_1: change pointer, use static variable memory.
after: 1,double_1_finalResponse
before: 1,double_1_finalResponse
doubleP_error1: the memory of at would be overlap some time.
after: 1,doubleP_err1
before: -2,旝= (这里已经失效了)
doubleP_error2: the memory could not be free which make memory leak.
after: 1,doubleP_err2