我的一个小程序,测验分配内存函数的,不知道为什么总是出错,请大家看一下,到底错在哪里了?

SteveYoung 2004-12-04 02:49:04
资源文件我使用VC++6.0的资源编辑器来编写
=======================================
这个是.rc资源脚本
-----------------------
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// Chinese (P.R.C.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDR_DLGMAIN DIALOG DISCARDABLE 0, 0, 295, 96
STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "系统信息及内存分配演示"
FONT 9, "Tahoma"
BEGIN
DEFPUSHBUTTON "系统信息",IDOK,161,44,50,24
PUSHBUTTON "退出程序",IDCANCEL,228,43,50,25
PUSHBUTTON "分配移动内存",IDC_ALLOCMOVEABLE,20,44,50,24
PUSHBUTTON "分配固定内存",IDC_ALLOCFIXED,89,44,50,24
END

IDR_SYSINFO DIALOG DISCARDABLE 0, 0, 215, 180
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "系统信息"
FONT 9, "Tahoma"
BEGIN
DEFPUSHBUTTON "确定",IDOK,81,148,50,14
CTEXT "",IDC_SYSINFOTEXT,27,22,158,93
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDR_DLGMAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 288
TOPMARGIN, 7
BOTTOMMARGIN, 89
END

IDR_SYSINFO, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 208
TOPMARGIN, 7
BOTTOMMARGIN, 173
END
END
#endif // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_ICON ICON DISCARDABLE "chip.ico"

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END

3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END

#endif // APSTUDIO_INVOKED

#endif // Chinese (P.R.C.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
---------------------------------------------------
这个是resource.h文件

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by memtest.rc
//
#define IDR_DLGMAIN 101
#define IDR_SYSINFO 102
#define IDR_ICON 103
#define IDC_ALLOCMOVEABLE 1000
#define IDC_ALLOCFIXED 1005
#define IDC_SYSINFOTEXT 1006

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1006
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
------------------------------------------------
















...全文
86 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
SteveYoung 2004-12-06
  • 打赏
  • 举报
回复
谢谢clumsy大哥的指点,非常感谢!!!

分不多,请见谅!!
SteveYoung 2004-12-05
  • 打赏
  • 举报
回复
自己up一下
clumsy 2004-12-05
  • 打赏
  • 举报
回复
GlobalAlloc() 函数分配具有 GMEM_FIXED 属性的内存块, 返回的值就是指向内存块的指针, 要访问相应的内存, 只需要简单地进行值的类型转换就可以了:
lpMemFixed = (LPBYTE)Globalalloc(GMEM_FIXED...)
不需要进行锁定或获取句柄之类的操作的. 它的句柄和内存块地址就是一致的.
这个特性在 GlobalAlloc 函数说明里应该是有的吧
SteveYoung 2004-12-04
  • 打赏
  • 举报
回复
to : clumsy(Kyrie eleison)

多谢大哥!非常感激你的提示,我已经解决了这个问题中的2个,还有一个小问题想问你,我在申请固定内存的时候,发现内存的句柄和内存的地址始终是同一个值,但是在输出那个信息的时候,我并没有把句柄跟地址搞混呀,这是为什么呢?难道申请的固定内存的句柄和地址本来就是一样的吗?

请再指教小弟一下好吗?
clumsy 2004-12-04
  • 打赏
  • 举报
回复
喔, 在申请内存之前, 没有给 @dwAllocByte 赋值, 申请的大小就错了
clumsy 2004-12-04
  • 打赏
  • 举报
回复
1. 由于你的 wsprintf 函数使用的用来生成提示信息的缓冲区, 只是定义了个指针啊, 没有定义成空间: local @lpMemMoveable[??]:BYTE ; ?? 要有足够的空间. 当然了, 也可以用刚申请到的内存空间来存放这个提示信息的. 不过, 这时就要注意 ADDR 的使用了, 因为申请到的空间本来就已经是地址了. 另外, GlobalFree 申请的空间之前, 是否应该 GlobalUnlock 一下呢? 因为你在申请之后使用了 GlobalLock
2. 和 3. 的问题, 我这里好像没有. "系统信息" 里面的对话框信息是完整的
SteveYoung 2004-12-04
  • 打赏
  • 举报
回复
有点乱,请大家原谅,可以copy到记事本中看一下,谢谢了
SteveYoung 2004-12-04
  • 打赏
  • 举报
回复
;(接上述程序)
_ProcDlgMain proc uses ebx esi edi hDlg, uMsg, wParam, lParam
local @lpMemMoveable
local @hMemMoveable

local @lpMemFixed
local @hMemFixed

local @szBufferMoveable
local @szBufferFixed

local @dwAllocByte

push hDlg
pop hDlgMain
mov eax, uMsg

.if eax == WM_CLOSE
invoke EndDialog, hDlgMain, NULL

.elseif eax == WM_INITDIALOG

invoke LoadIcon, hInstance, IDR_ICON
mov hIcon, eax
invoke SendMessage, hDlgMain, WM_SETICON, ICON_BIG, hIcon
mov @dwAllocByte, 1024

.elseif eax == WM_COMMAND
mov eax, wParam

.if ax == IDOK
invoke DialogBoxParam, hInstance, IDR_SYSINFO, hDlgMain, offset _ProcDlgAbout, NULL

.elseif ax == IDCANCEL
invoke EndDialog, hDlgMain, NULL

.elseif ax == IDC_ALLOCMOVEABLE ;此处申请可移动内存
invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, @dwAllocByte
.if eax ; 如果申请成功,则保存句柄
mov @hMemMoveable, eax
.endif

invoke GlobalLock, @hMemMoveable ; 锁定内存,保存指针
.if eax
mov @lpMemMoveable, eax
.endif

invoke wsprintf, addr @szBufferMoveable, addr szMoveableMemInfo, @hMemMoveable, @lpMemMoveable, @dwAllocByte
invoke MessageBox, hDlgMain, addr @szBufferMoveable, addr szMoveableMemCaption, MB_OK or MB_ICONINFORMATION
.if eax == MB_OK
invoke GlobalFree, @hMemMoveable
.endif

.elseif ax == IDC_ALLOCFIXED ;此处申请可移动内存
invoke GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, @dwAllocByte
.if eax ; 如果申请成功,则返回所申请地址的指针
mov @lpMemFixed, eax
.endif

invoke GlobalHandle, @lpMemFixed ; 根据指针获得内存块的句柄
.if eax
mov @hMemFixed, eax
.endif

invoke wsprintf, addr @szBufferFixed, addr szFixedMemInfo, @hMemFixed, @lpMemFixed, @dwAllocByte
invoke MessageBox, hDlgMain, addr @szBufferFixed, addr szFixedMemCaption, MB_OK or MB_ICONINFORMATION
.if eax == MB_OK
invoke GlobalFree, @hMemFixed
.endif
.endif
.else
mov eax, FALSE
ret

.endif
mov eax, TRUE
ret
_ProcDlgMain endp




start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke DialogBoxParam, hInstance, IDR_DLGMAIN, NULL, offset _ProcDlgMain, NULL
invoke ExitProcess, NULL

end start

==============
问题描述:

1.程序虽可以正常执行,但是在按下“分配移动内存”和“分配固定内存”按钮,弹出MessageBox之后,就会被Windows kill掉,不知道为什么,我已经做了内存指针的NULL判断;

2.我分配了1024Bytes的内存,可是在那个弹出的对话框中却显示我知分配了84bytes的内存,不知为何?

3.那个“invoke SetDlgItemText, hDlg, IDC_SYSINFOTEXT, addr @szBuffer”总是执行失败,返回值eax为0,所以另外的那个DlgAbout中总是什么都没有显示,不知为何?

=====
请各位大虾执教一下,我实在找不出来原因了,非常感谢!!!

我的系统:
Windows XP SP2 + 1G RAM
SteveYoung 2004-12-04
  • 打赏
  • 举报
回复

这个是源文件:
------------------------------------------------
.386
.model flat, stdcall
option casemap:none

include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib

IDR_DLGMAIN equ 101
IDR_SYSINFO equ 102
IDR_ICON equ 103
IDC_ALLOCMOVEABLE equ 1000
IDC_ALLOCFIXED equ 1005
IDC_SYSINFOTEXT equ 1006

.data?

hInstance dd ?
hDlgMain dd ?
hDlgAbout dd ?
hIcon dd ?

.const

szMemInfoText db '物理内存总数: %lu Bytes', 0dh, 0ah
db '空闲物理总数: %lu Bytes', 0dh, 0ah
db '虚拟内存总数: %lu Bytes', 0dh, 0ah
db '空闲虚拟内存: %lu Bytes', 0dh, 0ah
db '已用内存比例: %d%%', 0dh, 0ah
db '可用内存比例: %d%%', 0dh, 0ah
db '-----------------------------------------',0dh, 0ah
db '用户地址空间总数: %lu Bytes', 0dh, 0ah
db '用户可用地址空间: %lu Bytes', 0dh, 0ah,0

szMoveableMemInfo db '您申请的移动内存块句柄为: %d, 指针为: %d, 申请大小为: %d Bytes.', 0
szFixedMemInfo db '您申请的固定内存块句柄为: %d, 指针为: %d, 申请大小为: %d Bytes.', 0
szMoveableMemCaption db '移动内存块信息', 0
szFixedMemCaption db '固定内存块信息', 0

.code


_ProcDlgAbout proc uses ebx edi esi hDlg, wMsg, wParam, lParam
local @stMemInfo:MEMORYSTATUS
local @szBuffer[2048]:byte

push hDlg
pop hDlgAbout
mov eax, wMsg

.if eax == WM_CLOSE
invoke EndDialog, hDlgAbout, NULL

.elseif eax == WM_COMMAND

mov eax, wParam
.if ax == IDOK
invoke EndDialog, hDlgAbout, NULL
.endif

.elseif eax == WM_INITDIALOG
invoke SendMessage, hDlgAbout, WM_SETICON, ICON_BIG, hIcon
mov @stMemInfo.dwLength, sizeof @stMemInfo
invoke GlobalMemoryStatus, addr @stMemInfo
mov ebx, @stMemInfo.dwMemoryLoad ;ebx 中存放已用内存比例
mov edx, 100
sub edx, ebx ;edx 中存放可用内存比例

invoke wsprintf, addr @szBuffer, addr szMemInfoText, @stMemInfo.dwTotalPhys, @stMemInfo.dwAvailPhys,\
@stMemInfo.dwTotalPageFile, @stMemInfo.dwAvailPageFile, @stMemInfo.dwMemoryLoad, edx,\
@stMemInfo.dwTotalVirtual, @stMemInfo.dwAvailVirtual
invoke SetDlgItemText, hDlg, IDC_SYSINFOTEXT, addr @szBuffer


.else
mov eax, FALSE
ret

.endif

mov eax, TRUE
ret

_ProcDlgAbout endp

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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