vector和char*混用的困惑

时间:2022-11-16 04:26:52
哎,又来麻烦各位朋友了。

首先,我定义了一个结构体

typedef struct TSQLite3FieldDesc//数据库字段描述
{
char            m_szName[32];
char            m_szType[16];
bool m_bUnique;
char* m_DefaultValue;

TSQLite3FieldDesc();
TSQLite3FieldDesc(const char* lpszName,const char* lpszType,bool bUnique = false,const char* lpszDefaultValue = NULL);
~TSQLite3FieldDesc();
}TSQLite3FieldDesc;
typedef std::vector<TSQLite3FieldDesc> TSQLite3FieldDescs;

然后我在代码中pusuback一个东西进去了,有关问题的部分是这样的
首先,调用构造函数赋值,如下:

int DefaultValueLen = (int)strlen(lpszDefaultValue);
m_DefaultValue = new char[DefaultValueLen+1];
memcpy(m_DefaultValue,lpszDefaultValue,DefaultValueLen+1);

我跟踪进去发现没有问题的,调用结束后,m_DefaultValue的值为"abcd",假设我的lpszDefaultValue为"abcd"的话。

然后我再将赋值后的TSQLite3FieldDesc,pushback进入vector。
调用语句是,其中m_arrayFields定义:TSQLite3FieldDescs m_arrayFields;

m_arrayFields.push_back(TSQLite3FieldDesc(lpszName,lpszType,bUnique,lpszDefaultValue));//这一步我跟踪进来也是正确的

然后我在别的地方判断

if (m_arrayFields[i].m_DefaultValue)
{
    strSQL += " default '";
    //strSQL += m_arrayFields[i].m_DefaultValue;
    strSQL += m_arrayFields.at(i).m_DefaultValue;
    strSQL += "'";//这里就出问题了,m_arrayFields.at(i).m_DefaultValue的值就不是"abcd",而是"abcd         乱七八糟的汉字"了。
}

15 个解决方案

#1


第一:楼主好好的封装就行,不要用c语言的方式来实现c++.
第二:vector最好压入指针,而不是对象。否则,就要写operator==

#2


问题找到了,但是不知道该如何处理。
我在构造函数那里添加了如下语句,发现a依次等于 a b c d 0,这样是正确的,以0结尾嘛。

char a = m_DefaultValue[0];
a = m_DefaultValue[1];
a = m_DefaultValue[2];
a = m_DefaultValue[3];
a = m_DefaultValue[4];


我在pusuback进去后,再取值的地方再加如下指令,却出问题了。这个时候a依次等于 a b c d ?,也就是说没有了结束符。那到底是哪个步骤出问题了呢?

char a = m_arrayFields.at(i).m_DefaultValue[0];
a = m_arrayFields.at(i).m_DefaultValue[1];
a = m_arrayFields.at(i).m_DefaultValue[2];
a = m_arrayFields.at(i).m_DefaultValue[3];
a = m_arrayFields.at(i).m_DefaultValue[4];

#3


vector保存的是副本,所以你要提供一个良好的拷贝构造函数和operator==

#4


1楼的朋友可以说详细点么?谢谢!

#5


3楼的朋友,你指的是哪个需要提供“拷贝构造函数和operator==",是typedef struct TSQLite3FieldDesc么?

#6


3楼的朋友,谢谢你。的确是这个问题,vector是调用的拷贝构造函数。汗,我同步跟踪进去的时候居然没有提示我。哎
非常感谢!!

#7


引用 5 楼 yangyunzhao 的回复:
3楼的朋友,你指的是哪个需要提供“拷贝构造函数和operator==",是typedef struct TSQLite3FieldDesc么?


是的.因为你存放的是对象而不是对象的指针.所以你把这两个函数加进去试下.

#8


你传进去的值是一个TSQLite3FieldDesc对象,相当于给函数传值。那么函数push_back实际操作的是对象的副本,所以,其内容是有问题的。你最好传递指针

#9


引用 4 楼 yangyunzhao 的回复:
1楼的朋友可以说详细点么?谢谢!

你直接写成类的封装形式不是很好吗?
那还用什么typedef struct,这在c++里面根本不用,虽然也行。
还有一些的例外把这种情况看做是纯数据集合,根本不用写构造函数。直接当c用,
但是你又写了构造函数,这又是矛盾的。
所以,你应该多了解一下。

#10


lz可以看一下Effective STL中的条款3,对这类问题进行了深入的分析
http://dev.csdn.net/article/22/22868.shtm

#11


TSQLite3FieldDesc中重新写一个拷贝构造函数,因为这里要深拷贝~

#12


恩,我刚才重写了拷贝构造函数,为了安全,我也重新了operator=

#13


typedef struct TSQLite3FieldDesc//数据库字段描述
{
    char            m_szName[32];
    char            m_szType[16];
    bool        m_bUnique;
    char*        m_DefaultValue;     //你传入vector里的不是指针,而是拷贝副本,先不说效率影响,这里更会出问题了,vector的拷贝肯定是默认的,也就是说,你没有拷贝构造,  这种情况等同于发socket数据,传指针一样无效

    TSQLite3FieldDesc();
    TSQLite3FieldDesc(const char* lpszName,const char* lpszType,bool bUnique = false,const char* lpszDefaultValue = NULL);
    ~TSQLite3FieldDesc();
}TSQLite3FieldDesc;


#14


用boost::shared_ptr封装一下也行,也方面。

#15


基本理解了,先结贴了。分的不合理还请包容。谢谢

#1


第一:楼主好好的封装就行,不要用c语言的方式来实现c++.
第二:vector最好压入指针,而不是对象。否则,就要写operator==

#2


问题找到了,但是不知道该如何处理。
我在构造函数那里添加了如下语句,发现a依次等于 a b c d 0,这样是正确的,以0结尾嘛。

char a = m_DefaultValue[0];
a = m_DefaultValue[1];
a = m_DefaultValue[2];
a = m_DefaultValue[3];
a = m_DefaultValue[4];


我在pusuback进去后,再取值的地方再加如下指令,却出问题了。这个时候a依次等于 a b c d ?,也就是说没有了结束符。那到底是哪个步骤出问题了呢?

char a = m_arrayFields.at(i).m_DefaultValue[0];
a = m_arrayFields.at(i).m_DefaultValue[1];
a = m_arrayFields.at(i).m_DefaultValue[2];
a = m_arrayFields.at(i).m_DefaultValue[3];
a = m_arrayFields.at(i).m_DefaultValue[4];

#3


vector保存的是副本,所以你要提供一个良好的拷贝构造函数和operator==

#4


1楼的朋友可以说详细点么?谢谢!

#5


3楼的朋友,你指的是哪个需要提供“拷贝构造函数和operator==",是typedef struct TSQLite3FieldDesc么?

#6


3楼的朋友,谢谢你。的确是这个问题,vector是调用的拷贝构造函数。汗,我同步跟踪进去的时候居然没有提示我。哎
非常感谢!!

#7


引用 5 楼 yangyunzhao 的回复:
3楼的朋友,你指的是哪个需要提供“拷贝构造函数和operator==",是typedef struct TSQLite3FieldDesc么?


是的.因为你存放的是对象而不是对象的指针.所以你把这两个函数加进去试下.

#8


你传进去的值是一个TSQLite3FieldDesc对象,相当于给函数传值。那么函数push_back实际操作的是对象的副本,所以,其内容是有问题的。你最好传递指针

#9


引用 4 楼 yangyunzhao 的回复:
1楼的朋友可以说详细点么?谢谢!

你直接写成类的封装形式不是很好吗?
那还用什么typedef struct,这在c++里面根本不用,虽然也行。
还有一些的例外把这种情况看做是纯数据集合,根本不用写构造函数。直接当c用,
但是你又写了构造函数,这又是矛盾的。
所以,你应该多了解一下。

#10


lz可以看一下Effective STL中的条款3,对这类问题进行了深入的分析
http://dev.csdn.net/article/22/22868.shtm

#11


TSQLite3FieldDesc中重新写一个拷贝构造函数,因为这里要深拷贝~

#12


恩,我刚才重写了拷贝构造函数,为了安全,我也重新了operator=

#13


typedef struct TSQLite3FieldDesc//数据库字段描述
{
    char            m_szName[32];
    char            m_szType[16];
    bool        m_bUnique;
    char*        m_DefaultValue;     //你传入vector里的不是指针,而是拷贝副本,先不说效率影响,这里更会出问题了,vector的拷贝肯定是默认的,也就是说,你没有拷贝构造,  这种情况等同于发socket数据,传指针一样无效

    TSQLite3FieldDesc();
    TSQLite3FieldDesc(const char* lpszName,const char* lpszType,bool bUnique = false,const char* lpszDefaultValue = NULL);
    ~TSQLite3FieldDesc();
}TSQLite3FieldDesc;


#14


用boost::shared_ptr封装一下也行,也方面。

#15


基本理解了,先结贴了。分的不合理还请包容。谢谢