CArray 数据存储

曹小白 2016-08-04 04:21:26
VC++6.0
使用CArray定义了一个动态数组:typedef CArray< CClient,CClient > ClientArray;
struct CClient{
SOCKET m_socket;
LPCTSTR m_ip;
UINT m_prot;
};
定义全局变量:ClientArray g_CorpAccount;

在主线程中使用该数组:却发现每次存入新数据时,之前存入的数据全部被覆盖,但是数组长度确实在增加,怀疑与指针有关,但是不知道从哪里下手,请大神指导!
主线程部分代码如下:
UINT ServerThread(LPVOID lpParameter)
{
////无关内容省略
while (!server->m_bStopServer)
{
//处理入站连接,接受一个连接请求
ClientAddrLength=sizeof(ClientAddr);
if ((server->sDialog=accept(server->sListen,(sockaddr*)&ClientAddr,&ClientAddrLength))==INVALID_SOCKET)
{
return 0;
}
//获取客户端地址端口信息
ClientIP=inet_ntoa(ClientAddr.sin_addr);//连入客户端的信息
ClientPort=ClientAddr.sin_port;//连入客户端的信息

CClient item;
item.m_socket=server->sDialog;
item.m_ip=ClientIP;
item.m_prot=ClientPort;
g_CorpAccount.Add(item);

/////////////////////////////////////////////////////////////////以下无关内容省略
...全文
124 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
曹小白 2016-08-04
  • 打赏
  • 举报
回复
引用 8 楼 ddszhan 的回复:
是赋值了,把指针的地址值赋过去,但是指针所指向地址里保存的内容,在函数结束后就被释放了,这时候,就相当于你保存的指针,指向了一块曾经有效,但是现在无效的地方。
其实之前也用过一次, SOCKET accSock = accept(pChatRoom->m_listensock, (struct sockaddr *)&clientAddr , &iLen); if (accSock == INVALID_SOCKET) { continue; } clientitem item; item.m_Socket=accSock; item.m_strIp=inet_ntoa(clientAddr.sin_addr); int idx=pChatRoom->m_clientarray.Add(item); 这样子就没有问题啊,这是为什么?
ddszhan 2016-08-04
  • 打赏
  • 举报
回复
是赋值了,把指针的地址值赋过去,但是指针所指向地址里保存的内容,在函数结束后就被释放了,这时候,就相当于你保存的指针,指向了一块曾经有效,但是现在无效的地方。
曹小白 2016-08-04
  • 打赏
  • 举报
回复
引用 6 楼 ddszhan 的回复:
struct CClient{ SOCKET m_socket; LPCTSTR m_ip; UINT m_prot; }; 改成 struct CClient{ SOCKET m_socket; char m_ip[32]; ////////////// UINT m_prot; }; CClient item; item.m_socket=server->sDialog; item.m_ip=ClientIP; item.m_prot=ClientPort; g_CorpAccount.Add(item); 改成 CClient item; item.m_socket=server->sDialog; strcpy(item.m_ip, ClientIP); /////// item.m_prot=ClientPort; g_CorpAccount.Add(item);
阔以了!!结贴了!!谢谢了,阿里嘎多!!
ddszhan 2016-08-04
  • 打赏
  • 举报
回复
struct CClient{ SOCKET m_socket; LPCTSTR m_ip; UINT m_prot; }; 改成 struct CClient{ SOCKET m_socket; char m_ip[32]; ////////////// UINT m_prot; }; CClient item; item.m_socket=server->sDialog; item.m_ip=ClientIP; item.m_prot=ClientPort; g_CorpAccount.Add(item); 改成 CClient item; item.m_socket=server->sDialog; strcpy(item.m_ip, ClientIP); /////// item.m_prot=ClientPort; g_CorpAccount.Add(item);
曹小白 2016-08-04
  • 打赏
  • 举报
回复
引用 4 楼 ddszhan 的回复:
另外,结构体里还保存了一个字符串指针; ClientIP赋给item.m_ip后,出了函数,ClientIP就被释放了,item.m_ip就成野指针了。
那理论上,item_m_ip完成赋值之后,不是相当于完成了赋值的动作了吗?怎么就成了野指针了?
ddszhan 2016-08-04
  • 打赏
  • 举报
回复
另外,结构体里还保存了一个字符串指针; ClientIP赋给item.m_ip后,出了函数,ClientIP就被释放了,item.m_ip就成野指针了。
曹小白 2016-08-04
  • 打赏
  • 举报
回复
难道CARRAY不是动态分配内存吗?CARRARY难道不是相当于动态数组么?
ddszhan 2016-08-04
  • 打赏
  • 举报
回复
这种应用,一般CArray里保存指针,用动态分配的内存好些吧。
曹小白 2016-08-04
  • 打赏
  • 举报
回复
设置断点进行调试,在获取第一个数据之后,程序便无法继续!希望大家来出点主意!!
VC++ MFC 经典教程 - 基础篇 1.CP_YourFirstWindowsProgram.mp4 10.MFC_GDI_画直线和曲线.mp4 11.MFC_GDI_画椭圆_多边形及其他形状.mp4 12.MFC_GDI_画笔和画刷.mp4 13.MFC_GDI_画文本和字体.mp4 14.MFC_GDI_备用对象和取消选定.mp4 15.MFC_Ruler.mp4 16.MFC_窗口滚动条.mp4 17.MFC_Accel.mp4 18.MFC_Accel(2).mp4 19.MFC_消息框.mp4 2.Windows_编程模型.mp4 20MFC_客户区鼠标消息.mp4 21.MFC_TicTac-1.mp4 22.MFC_TicTac-2.mp4 23.MFC_TicTac-3.mp4 24.MFC_鼠标滚轮.mp4 25.MFC_捕获鼠标.mp4 26.MFC_VisualKB-1.mp4 27.MFC_VisualKB-2.mp4 29.MFC_菜单.mp4 3.MFC_第一个MFC程序设计.mp4 30.MFC_CButton类.mp4 31.MFC_E_FontView-1.mp4 32.MFC_E_FontView-2.mp4 33.MFC_CEdit类.mp4 34.MFC_MyPad.mp4 35.MFC_对话框_静态文本_编辑框.mp4 36.MFC_对话框_访问控件_7种方法_A.mp4 37.MFC_对话框_访问控件_7种方法_B.mp4 38.MFC_对话框_访问控件_7种方法_C.mp4 39.MFC_对话框_复选框_单选钮.mp4 4.MFC_消息映射.mp4 40.MFC_模态对话框.mp4 41.MFC_非模态对话框.mp4 42.MFC_属性表.mp4 43.MFC_公用对话框.mp4 44.MFC_数组类-1.mp4 45.MFC_数组类-2.mp4 46.MFC_CArray.mp4 47.MFC_列表类.mp4 48.MFC_映射类.mp4 49.MFC_类型指针类.mp4 5.MFC_使用向导快速进行MFC程序设计.mp4 50.MFC_CFile.mp4 51.MFC_CArchive.mp4 52.MFC_四个对象四种方法.mp4 53. MFC_Ruler.mp4 54.MFC_Ruler.mp4 55.MFC_Ruler.mp4 56.MFC_SdiSquares.mp4 57.MFC_Scroll_Ruler.mp4 58.MFC_CHtmlView.mp4 59.MFC_CTreeView.mp4 6.MFC_字符集和TEXT宏.mp4 60.MFC_CListView.mp4 61.MFC_MdiSquares.mp4 62.MFC_动态拆分窗口.mp4 63.MFC_ToolBar.mp4 64.MFC_ToolBar_Ex13a.mp4 65.MFC_StatusBar.mp4 66.MFC_StatusBar_Ex13b.mp4 67.MFC_Rebar.mp4 68.MFC_EZPrint.mp4 69.MFC_Print_Bubble.mp4 7.MFC_建立应用程序.mp4 8.MFC_第一个MFC程序设计(不用向导).mp4 9.MFC_Windows_GDI_设备描述表类.mp4 数据结构与算法_C语言 01.swap.mp4 02.BubbleSort.mp4 03.SelecttionSort.mp4 04.顺序查找.mp4 05.C_DS_折半查找.mp4 06.递归.mp4 07递归算法_折半查找.mp4 08.Permutations.mp4 09.插入排序.mp4 10.快速排序.mp4 11.归并排序.mp4 12.顺序栈.mp4 13.顺序队列.mp4 14.链表的基本概念.mp4 15.单链表的基本运算.mp4 16.循环单链表.mp4 17.双向链表.mp4 18.链式栈.mp4 19.链式队列.mp4 20.基数排序.mp4 21.树.mp4 22.二叉树的存储表示与实现.mp4 23.二叉树的遍历.mp4 24.二叉查找树.mp4 25.红黑树.mp4 26.堆.mp4 27.堆排序.mp4 28.哈希表.mp4 29.图_邻接矩阵
客户端开发文档 项目类别:基于对话框的MFC程序。 项目名称:MFCClient 一、 程序的初始化。 1、 在函数CMFCClientDlg::AddInit()中进行相应的操作。主要功能为对控件进行初始化。禁用控件和设置空间初始值。 2、 在CMFCClientDlg::InitInstance()中加载套接字库 二、 客户端单击“连接服务器”按钮后的操作。 1、 创建一个新线程,用于处理相关的SOCKET操作。线程函数为CMFCClientDlg的静态成员函数fnSocket(). 2、 fnSocket()的主要作用。 a、 使用函数CMFCClientDlg::CheckName(CString)对昵称进行检查 b、 创建套接字、检查输入的端口、与服务端进行连接以及循环接收来自服务端的消息。 c、 将应当禁用和开启的控件分别进行操作。 3、使用DisposeRecvMsg(Cstring str)对收到的消息进行处理。 三、 客户端单击“发送消息”按钮后的操作。 从文本控件中获得Cstring类型的数据,与想发送的目标客户端昵称根据之前的约定进行组合,然后转换为TCHAR的数据,再发送到所有的客户端。 四、 客户端单击“断开服务器”按钮后的操作 关闭套接字,此时,服务端将会收到关闭消息,从而作出相应的相应。 服务端开发文档 项目类别:基于对话框的MFC程序。 项目名称:MFCServer 一、 程序的初始化。 1、 在函数CMFCServerDlg::AddInit()中进行相应的操作。主要功能为对控件进行初始化。禁用控件和设置空间初始值。 2、 在CMFCServerApp::InitInstance()中加载套接字库 二、 服务端单击“开启服务器”按钮后的操作。 1、 创建一个新线程,用于处理相关的SOCKET操作。线程函数为CMFCServerDlg的静态成员函数fnSocket(). 2、 fnSocket()的主要作用。 a、 创建套接字、检查输入的端口、绑定套接字、监听端口以及使用select模型开始处理套接字。 b、 将应当禁用和开启的控件分别进行操作。 3、 维护用于存储客户端昵称和套机字的Carray数组m_ClientMap 4、 使用函数DisposeRecvMsg(SOCKET s,Cstring str)来处理消息接收到的消息。 三、 服务端单击“停止服务器”按钮后的操作。 清空相关的数据和对相关控件的禁用进行操作。 四、 服务端单击“发送消息”按钮后的操作。 从文本控件中获得Cstring类型的数据,然后转换为TCHAR的数据,再发送到所有的客户端。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧