请教,这几句代码是什么意思?

BAO BAO 2015-09-20 08:39:32
//#pragma comment(lib, "netapi32.lib")

#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <lm.h>

int main()
{
LPUSER_INFO_0 pBuf = NULL;
LPUSER_INFO_0 pTmpBuf;
DWORD dwEntriesRead = 0;
DWORD dwTotalEntries = 0;
DWORD dwResumeHandle = 0;
NET_API_STATUS nStatus;

do
{ nStatus = NetUserEnum((LPCWSTR) NULL, 0, FILTER_NORMAL_ACCOUNT, (LPBYTE*)&pBuf, MAX_PREFERRED_LENGTH,
&dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) // If the call succeeds,
{
if ((pTmpBuf = pBuf) != NULL) //疑问1:此处为什么判断!= NULL 外层if已经判断了If the call succeeds, 这个值就肯定不会是空啊?为啥要多此一举?
{
for (DWORD i = 0; (i < dwEntriesRead); i++) // Loop through the entries.
{
assert(pTmpBuf != NULL); //疑问2:这句话是什么意思 我觉得好像不起作用
if (pTmpBuf == NULL) //疑问3: 我觉的应该此处没有为空的可能性啊
{
fprintf(stderr, "An access violation has occurred\n");
break;
}
wprintf(L"%s\n", pTmpBuf->usri0_name); // Print the name of the user account.
pTmpBuf++;
}
}
}

// Free the allocated buffer.
if (pBuf != NULL)
{
NetApiBufferFree(pBuf);
pBuf = NULL; //疑问4:这里如果不设pBuf = NULL,有严重后果吗?
}
}
// Continue to call NetUserEnum while there are more entries.
while (nStatus == ERROR_MORE_DATA); // end do

// Check again for allocated memory. 疑问5:循环体里面不是每次都释放了吗 最后在释放有必要吗?
if (pBuf != NULL) NetApiBufferFree(pBuf);

return 0;
}



除了上述几个小菜问题,我还想问下大家 如果代码不用临时指针pTmpBuf 怎么释放pBuf?有什么方法?
...全文
176 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
BAO BAO 2015-09-21
  • 打赏
  • 举报
回复
引用 2 楼 fly_dragon_fly 的回复:
1 括号里是等号, 不是判断 2 断言 仅工作在debug下 3 release下assert不生效, 还是要判断的 4 不知道, 看NetApiBufferFree多次传同一个会不会有问题了 5 确实多余 lpBuf类型是BYTE *, 而tmpbuf是LPUSER_INFO_0, 只是为了用这个结构指针而已
回答的很好,我发的例子是msdn上的例子,有些看不懂就发上来了。 我若写成如下代码,请问大家,这样写有什么bug吗?比重要的判断 没判断 或者在什么区情况下会得出不准确的结果。
#include <stdio.h>
#include <windows.h> 
#include <lm.h>
#pragma comment(lib, "netapi32.lib")

int main()
{
   LPUSER_INFO_0 pBuf = NULL;
   LPUSER_INFO_0 pTmpBuf;
   NET_API_STATUS nStatus; 
   DWORD dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0;  
   do
   {  nStatus = NetUserEnum((LPCWSTR) NULL, 0, FILTER_NORMAL_ACCOUNT, (LPBYTE*)&pBuf, MAX_PREFERRED_LENGTH,
                            &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);        
      if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))	// If the call succeeds,  
      {
            pTmpBuf = pBuf;          
            for (DWORD i = 0; (i < dwEntriesRead); i++)	// Loop through the entries.
            {              
               wprintf(L"%s\n", pTmpBuf->usri0_name);	//  Print the name of the user account.
               pTmpBuf++;
            }
      }           
      if (pBuf != NULL){NetApiBufferFree(pBuf); pBuf = NULL;}	// Free the allocated buffer.  保留这句好
   }while (nStatus == ERROR_MORE_DATA);     
   //if (pBuf != NULL) NetApiBufferFree(pBuf);	// Check again for allocated memory. 还是保留这句好呢  不是说重复了吗
   return 0;
}
赵4老师 2015-09-21
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
ztenv 版主 2015-09-21
  • 打赏
  • 举报
回复
引用 4 楼 fly_dragon_fly 的回复:
[quote=引用 3 楼 lianshaohua 的回复:] [quote=引用 2 楼 fly_dragon_fly 的回复:] 1 括号里是等号, 不是判断 2 断言 仅工作在debug下 3 release下assert不生效, 还是要判断的 4 不知道, 看NetApiBufferFree多次传同一个会不会有问题了 5 确实多余 lpBuf类型是BYTE *, 而tmpbuf是LPUSER_INFO_0, 只是为了用这个结构指针而已
好好学习基础知识,尤其是很多不懂的可以百度或谷歌,[/quote]这是说我回答错了吗[/quote] 引发如此大的误会
fly_dragon_fly 2015-09-21
  • 打赏
  • 举报
回复
引用 3 楼 lianshaohua 的回复:
[quote=引用 2 楼 fly_dragon_fly 的回复:] 1 括号里是等号, 不是判断 2 断言 仅工作在debug下 3 release下assert不生效, 还是要判断的 4 不知道, 看NetApiBufferFree多次传同一个会不会有问题了 5 确实多余 lpBuf类型是BYTE *, 而tmpbuf是LPUSER_INFO_0, 只是为了用这个结构指针而已
好好学习基础知识,尤其是很多不懂的可以百度或谷歌,[/quote]这是说我回答错了吗
ztenv 版主 2015-09-21
  • 打赏
  • 举报
回复
引用 2 楼 fly_dragon_fly 的回复:
1 括号里是等号, 不是判断 2 断言 仅工作在debug下 3 release下assert不生效, 还是要判断的 4 不知道, 看NetApiBufferFree多次传同一个会不会有问题了 5 确实多余 lpBuf类型是BYTE *, 而tmpbuf是LPUSER_INFO_0, 只是为了用这个结构指针而已
好好学习基础知识,尤其是很多不懂的可以百度或谷歌,
fly_dragon_fly 2015-09-21
  • 打赏
  • 举报
回复
1 括号里是等号, 不是判断 2 断言 仅工作在debug下 3 release下assert不生效, 还是要判断的 4 不知道, 看NetApiBufferFree多次传同一个会不会有问题了 5 确实多余 lpBuf类型是BYTE *, 而tmpbuf是LPUSER_INFO_0, 只是为了用这个结构指针而已
BAO BAO 2015-09-21
  • 打赏
  • 举报
回复
木有人吗,,,
纵横车 2015-09-21
  • 打赏
  • 举报
回复
感觉你的几个疑问都是一些编程规范之类的问题,写不写没大差别。 如果不用pTmpBuf那么就要把在for循环里指针递增的值减回去,比如可以减去(dwEntriesRead-1)。

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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