1 #include <iostream> 2 #include <vector> 3 #include <string.h> 4 5 using namespace std; 6 7 struct A{ 8 int a; 9 char b[88]; 10 char c[88]; 11 }; 12 13 typedef enum { 14 TYPE_INT = 1, 15 TYPE_VARCHAR2 = 2, 16 TYPE_DATE 17 }ORA_DATATYPE_E; 18 19 typedef struct { 20 ORA_DATATYPE_E type; 21 void * addr; 22 }ORA_ABSTRACT_DATA_T; 23 24 void func(const vector<ORA_ABSTRACT_DATA_T> & vec) { 25 for (int i = 0; i < (int)vec.size(); i++) { 26 if (vec[i].type == TYPE_INT) { 27 std::cout << "int : " << *((int *)vec[i].addr) << std::endl; 28 } else if (vec[i].type == TYPE_VARCHAR2) { 29 std::cout << "varchar2 : " << (char *)vec[i].addr << std::endl; 30 } 31 } 32 } 33 34 int main(void) { 35 36 struct A a; 37 38 memset(&a, 0, sizeof(a)); 39 40 a.a = 4; 41 memcpy(a.b, "abcd", strlen("abcd")); 42 memcpy(a.c, "efgh", strlen("efgh")); 43 44 vector<ORA_ABSTRACT_DATA_T> vec; 45 ORA_ABSTRACT_DATA_T data; 46 47 data.type = TYPE_INT; 48 data.addr = (void *) new int; 49 memcpy(data.addr, &a.a, sizeof(a.a)); 50 vec.push_back(data); 51 52 data.type = TYPE_VARCHAR2; 53 data.addr = (void *) new char[strlen(a.b)]; 54 memcpy(data.addr, a.b, strlen(a.b)); 55 vec.push_back(data); 56 57 data.type = TYPE_VARCHAR2; 58 data.addr = (void *) new char[strlen(a.c)]; 59 memcpy(data.addr, a.c, strlen(a.c)); 60 vec.push_back(data); 61 62 func(vec); 63 64 for (int i = 0; i < (int)vec.size(); i++) { 65 if (vec[i].type == TYPE_INT) { 66 if (vec[i].addr) { 67 delete (int *)vec[i].addr; 68 vec[i].addr = NULL; 69 } 70 } else if (vec[i].type == TYPE_VARCHAR2) { 71 if (vec[i].addr) { 72 delete (char *)vec[i].addr; 73 vec[i].addr = NULL; 74 } 75 } 76 } 77 78 vec.clear(); 79 80 }
我想用这种方式,将一个大型结构体中的数据存放到vector中,这样就可以在get数据库SQL插入语句时,使用for循环来bind参数,不用把结构体中的变量一一列举出来了。
现在这样写,在本机运行是正常的,但理论上是不是存在什么风险呢?
小弟看了一下,个人觉得,就这个程序感觉很棒。在我的理解范围内,应该没有。结构体中,使用指针,要防止浅拷贝。使用了数组,防止越界。嘿嘿,就知道这么多了。如有不对,还请指正。
其实
data.addr = (void *) new char[strlen(a.b)];
应该改成
data.addr = (void *) new char[strlen(a.b) +1];
来保证存在一位结束符
@豪放婉约派程序员: AIYA,越简单越容易忽略。
~~(╯﹏╰)b 除了教材,还从来没遇到过这种代码。 代码一般看看不粗来,最好是运行一下。
这样做没什么必要, 参数拷贝一份, 无谓的开销.
你的思路可以尝试(但是需要扩展很多类型), 但是你代码语法存在问题. 你好像写的不是C++, 是 "乱炖".
1. string.h 是什么鬼, 不都是 cstring?
2. 88是什么鬼(A, a, b, c 也可以忍受) , 魔法数字是万恶之源
3. typedef enum { ... } xxx 是什么鬼, 那是c 不是C++ , 不需要 typedef .. 推荐学习深入了解 纯粹的 C++
4. (int)vec.size() 是什么鬼, 编译器知道 二者怎么比较, 不需要强转 , 最终以大类型为主比较的
5. struct A a; 这是什么鬼, C++ 不是 c, A a;就可以了
6. memset 0 了, 每次都这么写直接放在 A 结构体的构造函数中就可以了. C++ 类和结构推荐用构造函数初始化
6. (int *)vec[i].addr 不地道, C++ 推荐 static_cast
7. std::cout 和 using namespace std; 是画蛇添足, 推荐删掉 using 声明空间.
8. strlen("abcd") 是可以记着, 没必要每次都是 来一遍求长度 , O(n) 级别的浪费
9. 后面 delete , 对于你那个 int char * 完全可以, 后面可以优化 .
直接 delete vec[i].addr; 销毁, 因为没有特殊的析构需要执行
10. 你是 int mian ... 然而 return 0; 或者 exit(EXIT_SUCCESS); 呢, 又消失了~~~
上面就是你的问题, 更加合适的可以看 boost::any C++ 结构.
最后补充一条, 你要是说你是 C + STL 我也算了, 来个 strlen("xxxx") , C字符串隐藏BUG之源呀.
要多看教程, 多做题呀.....
别人这样写可以啊。。你这纯粹是瞎找错。。这是BUG吗??并且你写的mian是什么玩意。。
@蛤?蛤!: 那时候年轻, 工作用C++, 现在应该都不会了. 多见谅
@喜欢兰花山丘: emmm
我个人感觉应该没有什么bug了。