很奇怪的问题,关于malloc和new

iamyg 2014-03-13 07:19:11
搞了一下午,搞不清是为何产生这种情况。
具体情况是这样子的,代码中注释的部分,我刚开始使用malloc申请内存,发现一只报堆错误。
无奈,想着试试new 和 delete,发现竟然啥也不报了
其中 DATA_FILE_LIST 是一个结构体,定义如下
typedef struct
{
unsigned short m_FILEID; //文件ID
unsigned short m_Reserve; //保留,用于4字节对齐
DATA_FILE_ATTR m_attr; //文件属性

}DATA_FILE_LIST;

废话不说,直接上代码
DATA_FILE_LIST *dataFileList = NULL;
int dataLen = 32*sizeof(DATA_FILE_LIST);
//获取总共所需要的缓冲区长度
dwRet = Dongle_ListFile(hDongle, FILE_DATA, NULL, &dataLen);
if ((dwRet != DONGLE_SUCCESS)&&(dwRet != DONGLE_FILE_NOT_FOUND))
{
AfxMessageBox("获取文件列表缓冲区长度出错!");
dwRet = Dongle_Close(hDongle);
return;
}
if (dwRet == DONGLE_FILE_NOT_FOUND)
{
dataLen = 0;
}
//计算总共有几个文件
int fileCnt = dataLen / sizeof(DATA_FILE_LIST);
//申请内存,并获取列表
if (fileCnt > 0)
{
dataFileList = new DATA_FILE_LIST[sizeof(dataFileList)*fileCnt];
//********************此处用malloc的话可以操作,但是施放有问题*****************
//dataFileList = (DATA_FILE_LIST *)malloc(sizeof(dataFileList)*fileCnt);
dwRet = Dongle_ListFile(hDongle, FILE_DATA, (void *)dataFileList, &dataLen);
if (dwRet != DONGLE_SUCCESS)
{
AfxMessageBox("获取文件列表出错!");
dwRet = Dongle_Close(hDongle);
return;
}
//遍历删除文件
for (int i=0; i<fileCnt; i++)
{
dwRet = Dongle_DeleteFile(hDongle, FILE_DATA, dataFileList[i].m_FILEID);
if (dwRet != DONGLE_SUCCESS)
{
AfxMessageBox("删除文件出错!");
dwRet = Dongle_Close(hDongle);
return;
}
}
if (dataFileList != NULL)
{
delete [] dataFileList;
//**********报堆错误**********
//free(dataFileList);
dataFileList = NULL;
}
}


环境是 vs2010 + win7x64
请教各位大神,这是为何?
...全文
275 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamyg 2014-03-17
  • 打赏
  • 举报
回复
引用 16 楼 xx306 的回复:
2楼就已经为你指出了错误。sizeof(dataFileList)计算的是指针的大小,因为dataFileList就是一个指针而已,在32位机上是4,不信你可以用小程序测一下,而你的目的是计算对象的大小,应该是12,因为你没有定义对象,所以使用sizeof(DATA_FILE_LIST)是正确的。
谢谢,明白了,太感谢了。结贴
Ashily_1020 2014-03-17
  • 打赏
  • 举报
回复
如果是给内置类型的话,可以用malloc和free,由系统负责分配和释放内存,速度会比new和delete快一些,但是如果是类类型或者结构类型的话,malloc只会分配内存,不会调用构造函数,而new会,最好就用new
赵4老师 2014-03-17
  • 打赏
  • 举报
回复
new Operator The new operator attempts to dynamically allocate (at run time) one or more objects of type-name. The new operator cannot be used to allocate a function; however, it can be used to allocate a pointer to a function. Syntax allocation-expression : ::opt new placementopt new-type-name new-initializeropt ::opt new placementopt ( type-name ) new-initializeropt placement : ( expression-list ) new-type-name : type-specifier-list new-declaratoropt The new operator is used to allocate objects and arrays of objects. The new operator allocates from a program memory area called the “free store.” In C, the free store is often referred to as the “heap.” When new is used to allocate a single object, it yields a pointer to that object; the resultant type is new-type-name * or type-name *. When new is used to allocate a singly dimensioned array of objects, it yields a pointer to the first element of the array, and the resultant type is new-type-name * or type-name *. When new is used to allocate a multidimensional array of objects, it yields a pointer to the first element of the array, and the resultant type preserves the size of all but the leftmost array dimension. For example: new float[10][25][10] yields type float (*)[25][10]. Therefore, the following code will not work because it attempts to assign a pointer to an array of float with the dimensions [25][10] to a pointer to type float: float *fp; fp = new float[10][25][10]; The correct expression is: float (*cp)[25][10]; cp = new float[10][25][10]; The definition of cp allocates a pointer to an array of type float with dimensions [25][10] — it does not allocate an array of pointers. All but the leftmost array dimensions must be constant expressions that evaluate to positive values; the leftmost array dimension can be any expression that evaluates to a positive value. When allocating an array using the new operator, the first dimension can be zero — the new operator returns a unique pointer. The type-specifier-list cannot contain const, volatile, class declarations, or enumeration declarations. Therefore, the following expression is illegal: volatile char *vch = new volatile char[20]; The new operator does not allocate reference types because they are not objects. If there is insufficient memory for the allocation request, by default operator new returns NULL. You can change this default behavior by writing a custom exception-handling routine and calling the _set_new_handler run-time library function with your function name as its argument. For more details on this recovery scheme, see The operator new Function.
赵4老师 2014-03-17
  • 打赏
  • 举报
回复
malloc Allocates memory blocks. void *malloc( size_t size ); Routine Required Header Compatibility malloc <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT For additional compatibility information, see Compatibility in the Introduction. Libraries LIBC.LIB Single thread static library, retail version LIBCMT.LIB Multithread static library, retail version MSVCRT.LIB Import library for MSVCRT.DLL, retail version Return Value malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small. Parameter size Bytes to allocate Remarks The malloc function allocates a memory block of at least size bytes. The block may be larger than size bytes because of space required for alignment and maintenance information. The startup code uses malloc to allocate storage for the _environ, envp, and argv variables. The following functions and their wide-character counterparts also call malloc: calloc fscanf _getw setvbuf _exec functions fseek _popen _spawn functions fgetc fsetpos printf _strdup _fgetchar _fullpath putc system fgets fwrite putchar _tempnam fprintf getc _putenv ungetc fputc getchar puts vfprintf _fputchar _getcwd _putw vprintf fputs _getdcwd scanf fread gets _searchenv The C++ _set_new_mode function sets the new handler mode for malloc. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when malloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call _set_new_mode(1) early in your program, or link with NEWMODE.OBJ. When the application is linked with a debug version of the C run-time libraries, malloc resolves to _malloc_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support. Example /* MALLOC.C: This program allocates memory with * malloc, then frees the memory with free. */ #include <stdlib.h> /* For _MAX_PATH definition */ #include <stdio.h> #include <malloc.h> void main( void ) { char *string; /* Allocate space for a path name */ string = malloc( _MAX_PATH ); if( string == NULL ) printf( "Insufficient memory available\n" ); else { printf( "Memory space allocated for path name\n" ); free( string ); printf( "Memory freed\n" ); } } Output Memory space allocated for path name Memory freed Memory Allocation Routines See Also calloc, free, realloc
DM306 2014-03-16
  • 打赏
  • 举报
回复
2楼就已经为你指出了错误。sizeof(dataFileList)计算的是指针的大小,因为dataFileList就是一个指针而已,在32位机上是4,不信你可以用小程序测一下,而你的目的是计算对象的大小,应该是12,因为你没有定义对象,所以使用sizeof(DATA_FILE_LIST)是正确的。
iamyg 2014-03-16
  • 打赏
  • 举报
回复
引用 14 楼 lovesmiles 的回复:
如果是运行时报的错误,可能是malloc的内存的边界在函数调用中被破坏了,所以free出错。仔细检查下用到这个指针的函数的内部
运行时错误,我是结构体套了结构体,不过大小看起来正常那,所以觉得很奇怪,不知道啥原因 希望高手赐教
qq120848369 2014-03-16
  • 打赏
  • 举报
回复
1,sizeof(dataFileList)是指针大小,应改为sizeof(*dataFileList) 2,ew DATA_FILE_LIST[sizeof(dataFileList)*fileCnt]; 的sizeof()可以删了,只需要告诉new申请几个元素即可。
iamyg 2014-03-14
  • 打赏
  • 举报
回复
引用 2 楼 wxf54318 的回复:
malloc和new都是在堆中动态分配内存,在分配内存上是等价的 dataFileList = new DATA_FILE_LIST[sizeof(dataFileList)*fileCnt];你这句话让人费解 应该是dataFileList = new DATA_FILE_LIST[fileCnt];吧
对对对,这里有问题
iamyg 2014-03-14
  • 打赏
  • 举报
回复
引用 1 楼 bbs2241 的回复:
dataFileList = (DATA_FILE_LIST *)malloc(sizeof(DATA_FILE_LIST)*fileCnt);
写代码要细心哦
这里没问题的那,我要的是DATA_FILE_LIST的数组 new那里确实有问题,不应该*前面的
ultimater 2014-03-14
  • 打赏
  • 举报
回复
new表达示后面不用加sizeof表达示……
starytx 2014-03-14
  • 打赏
  • 举报
回复
new操作符后边的数值是元素个数而不是总大小,因为已经有一个类型了,编译器会自己计算,所以不需要sizeof(xxxx),直接写个数,malloc需要自己计算要开辟的空间大小
dbzhang800 2014-03-14
  • 打赏
  • 举报
回复
看来你需要补补基础了 sizeof(dataFileList) == sizeof(DATA_FILE_LIST*) == sizeof (int *) == sizeof (char *) == ...
iamyg 2014-03-14
  • 打赏
  • 举报
回复
引用 5 楼 dbzhang800 的回复:
[quote=引用 3 楼 iamyg 的回复:] [quote=引用 1 楼 bbs2241 的回复:]
dataFileList = (DATA_FILE_LIST *)malloc(sizeof(DATA_FILE_LIST)*fileCnt);
写代码要细心哦
这里没问题的那,我要的是DATA_FILE_LIST的数组 new那里确实有问题,不应该*前面的[/quote] malloc 和 new 两个地方你都弄错了,前者分配的太少了,后者又分配的太多了。[/quote] malloc 那里没问题吧,分配的不少那,因为接下来的操作都完全可以,只是到free时候报错了 还请指导一下,谢谢。
勤奋的小游侠 2014-03-14
  • 打赏
  • 举报
回复
如果是运行时报的错误,可能是malloc的内存的边界在函数调用中被破坏了,所以free出错。仔细检查下用到这个指针的函数的内部
dbzhang800 2014-03-14
  • 打赏
  • 举报
回复
引用 3 楼 iamyg 的回复:
[quote=引用 1 楼 bbs2241 的回复:]
dataFileList = (DATA_FILE_LIST *)malloc(sizeof(DATA_FILE_LIST)*fileCnt);
写代码要细心哦
这里没问题的那,我要的是DATA_FILE_LIST的数组 new那里确实有问题,不应该*前面的[/quote] malloc 和 new 两个地方你都弄错了,前者分配的太少了,后者又分配的太多了。
勤奋的小游侠 2014-03-14
  • 打赏
  • 举报
回复
报的是编译错误还是运行错误
iamyg 2014-03-14
  • 打赏
  • 举报
回复
引用 9 楼 ultimater 的回复:
new表达示后面不用加sizeof表达示……
谢谢指正,这里是写的有问题
iamyg 2014-03-14
  • 打赏
  • 举报
回复
引用 8 楼 starytx 的回复:
new操作符后边的数值是元素个数而不是总大小,因为已经有一个类型了,编译器会自己计算,所以不需要sizeof(xxxx),直接写个数,malloc需要自己计算要开辟的空间大小
对,这里是有问题,这里是写错了,谢谢指正
iamyg 2014-03-14
  • 打赏
  • 举报
回复
引用 7 楼 dbzhang800 的回复:
看来你需要补补基础了

sizeof(dataFileList) == sizeof(DATA_FILE_LIST*) == sizeof (int *) == sizeof (char *) == ...


没有错的
那个sizeof(dataFileList) == sizeof(DATA_FILE_LIST*) 不想等的
截图为证
[yabao=截图][/yabao]
wxf54318 2014-03-13
  • 打赏
  • 举报
回复
malloc和new都是在堆中动态分配内存,在分配内存上是等价的 dataFileList = new DATA_FILE_LIST[sizeof(dataFileList)*fileCnt];你这句话让人费解 应该是dataFileList = new DATA_FILE_LIST[fileCnt];吧
加载更多回复(1)

64,654

社区成员

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

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