void GetMemory2(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
  char *str=NULL;
  GetMemory=(&str);
  strcpy(str,"hello world");
  printf(str);

经典的问题,这段函数是运行正常的,但是明显内存泄漏,如何释放这段函数malloc的空间啊
在Test()中free(str);或者free(&str);程序都崩溃啊 

解决方案 »

  1.   

    你这段代码明显编译不过啊,GetMemory=(&str);是什么?如果是GetMemory2(&str);你参数个数也不对啊。
    void GetMemory2(char **p, int num)
    {
    *p = (char *)malloc(sizeof(char) * num);
    }
    void Test(void)
    {
      char *str=NULL;
      GetMemory2(&str,100);
      strcpy(str,"hello world");
      printf(str);
      free(str);
    }  没问题的
      

  2.   

    #include <stdio.h>
    #include <string.h>
    #include <malloc.h>void GetMemory(char **p, int num)
    {
    *p = (char *)malloc(sizeof(char) * num);
    }
    int main()
    {
    char *str=NULL;
    GetMemory(&str, 50);
    strcpy(str,"hello world");
    printf(str);
    free(str); return 0;
    }
      

  3.   

    那个是我敲错了,那这段代码,释放为什么会崩溃
    DWORD GetPhysicalDriveFromPartitionLetter(TCHAR letter)
    {
    HANDLE hDevice;               // handle to the drive to be examined
    BOOL result;                 // results flag
    DWORD readed;                   // discard results
    STORAGE_DEVICE_NUMBER number;   //use this to get disk numbers TCHAR path[MAX_PATH];
    _stprintf_s(path,MAX_PATH,TEXT("\\\\.\\%c:"), letter); hDevice = CreateFile(path, // drive to open
    GENERIC_READ | GENERIC_WRITE,    // access to the drive
    FILE_SHARE_READ | FILE_SHARE_WRITE,    //share mode
    NULL,             // default security attributes
    OPEN_EXISTING,    // disposition
    0,                // file attributes
    NULL);            // do not copy file attribute
    if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
    {
    //fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
    return DWORD(-1);
    } result = DeviceIoControl(
    hDevice,                // handle to device
    IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode
    NULL,                            // lpInBuffer
    0,                               // nInBufferSize
    &number,           // output buffer
    sizeof(number),         // size of output buffer
    &readed,       // number of bytes returned
    NULL      // OVERLAPPED structure
    );
    if (!result) // fail
    {
    //fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld\n", GetLastError());
    CloseHandle(hDevice);
    hDevice = INVALID_HANDLE_VALUE;
    return (DWORD)-1;
    }
    //printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber); CloseHandle(hDevice);
    hDevice = INVALID_HANDLE_VALUE;
    return number.DeviceNumber;
    }//
    //获取一个物理硬盘上有几个分区
    DWORD GetPartitionLetterFromPhysicalDrive(DWORD phyDriveNumber, TCHAR **letters)
    {
    DWORD mask;
    DWORD driveType;
    DWORD bmLetters;
    DWORD diskNumber;
    TCHAR path[MAX_PATH]; 
    TCHAR letter;
    DWORD letterNum;
    WORD i;
    TCHAR *p; bmLetters = GetLogicalDrives();
    if (0 == bmLetters)
    {
    return (DWORD)-1;
    } letterNum = 0;
    for (i = 0; i < sizeof(DWORD) * 8; i++)
    {
    mask = 0x1u << i;
    if ((mask & bmLetters) == 0)        //get one letter
    {
    continue;
    }
    letter = (CHAR)(0x41 + i);    //ASCII change
    //sprintf(path, "%c:\\", letter);
    _stprintf_s(path,MAX_PATH,TEXT("%c:\\"),letter);
    driveType = GetDriveType(path);
    if (driveType != DRIVE_FIXED)
    {
    bmLetters &= ~mask;     //clear this bit
    continue;
    }
    diskNumber = GetPhysicalDriveFromPartitionLetter(letter);
    if (diskNumber != phyDriveNumber)
    {
    bmLetters &= ~mask;     //clear this bit
    continue;
    }
    letterNum++;
    } //build the result
    *letters = (TCHAR *)malloc(letterNum);
    memset(letters,letterNum,0);
    if (NULL == *letters)
    {
    return (DWORD)-1;
    }
    p = *letters;
    for (i = 0; i < sizeof(DWORD) * 8; i++)
    {
    mask = 0x1u << i;
    if ((mask & bmLetters) == 0)
    {
    continue;
    }
    letter = (CHAR)(0x41 + i);    //ASCII change
    *p = letter;
    p++;
    } return letterNum;
    } TCHAR * lpLetters = NULL;
    DWORD dwLetters = GetPartitionLetterFromPhysicalDrive(0,&lpLetters);
    free(lpLetters);
      

  4.   

    单步到free(lpLetters);崩溃了,也是二重指针啊
      

  5.   

    //build the result
    那里,你letters数组长只有letterNum,而后面循环却有sizeof(DWORD) * 8次,很可能就超界了,你在循环中什么检查都没做。超界了就会破坏内存分配链,free当然就挂了。
        p = *letters;
    int nCount = 0;
        for (i = 0; i < sizeof(DWORD) * 8; i++)
        {
            mask = 0x1u << i;
            if ((mask & bmLetters) == 0)
            {
                continue;
            }
            letter = (CHAR)(0x41 + i);    //ASCII change
            *p = letter;
            p++;
    nCount++;
        }
    if (nCount > letterNum)
    {
    ASSERT(FALSE);
    }自己看看执行完后次数对不对
      

  6.   


    我这边得到,nCount == letterNum,都是4
      

  7.   

    你把每次 malloc函数的返回值记录一下,再和free的参数值对比一下就清楚了, 应该你有两次free的参数相同,第二次的时候, 分配的空间地址已被回收,所以异常了.
      

  8.   

    虽然这句等于没有执行,但是memset(letters,letterNum,0);是干什么的?
    STORAGE_DEVICE_NUMBER的定义是什么,发上来看看。
      

  9.   


    typedef struct _STORAGE_DEVICE_NUMBER {    //
        // The FILE_DEVICE_XXX type for this device.
        //    DEVICE_TYPE DeviceType;    //
        // The number of this device
        //    DWORD       DeviceNumber;    //
        // If the device is partitionable, the partition number of the device.
        // Otherwise -1
        //    DWORD       PartitionNumber;
    } STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;
      

  10.   

    winioctl.h 其实那段代码,可以直接编译通过的。
      

  11.   


    *letters = (TCHAR *)malloc(letterNum * sizeof(TCHAR));
    memset(*letters, 0, letterNum * sizeof(TCHAR));
      

  12.   


    *letters = (TCHAR *)malloc(letterNum * sizeof(TCHAR));
    memset(*letters, 0, letterNum * sizeof(TCHAR));
      

  13.   

    你内存没分配够
        //build the result
        *letters = (TCHAR *)malloc(letterNum*sizeof(TCHAR));
        memset(*letters,0,letterNum*sizeof(TCHAR));
        if (NULL == *letters)
        {
            return (DWORD)-1;
        }
        p = *letters;
        for (i = 0; i < sizeof(DWORD) * 8; i++)
        {
            mask = 0x1u << i;
            if ((mask & bmLetters) == 0)
            {
                continue;
            }
            letter = (CHAR)(0x41 + i);    //ASCII change
            *p = letter;
            p++;
        }
      

  14.   

    1 你这个不是 “释放二级指针”。
    2 乍一看,不知道你循环 sizeof(DWORD) * 8 次是啥意思(深究是在太费时间)。
    3 你也可以用 GetLogicalDriveStrings