关于内存分配和指针移动,请教大家

flamingwolf 2015-05-28 08:29:19
从网上拔下来个程序
发现内存分配时存在问题
到了后面无法释放
请高手指点以下撒
先感谢了



/* 主程序*/

// matrixleaktest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
// #include "vld.h"

int _tmain(int argc, _TCHAR* argv[])
{
int nrows,ncols;
nrows = 5 ;
ncols = 3 ;

float **row, **col,**theta,**y;
unsigned char **edgemap;


/* 源程序提供的内存机制,-1等参数设置存在问题 */
row = (float **)matrix(nrows, ncols, 0, 0, sizeof(float)); // 内存能够申请且后面可以释放
col = (float **)matrix(nrows, ncols, 0, 0, sizeof(float)); // 内存能够申请且后面可以释放
edgemap = (unsigned char **) matrix(nrows,ncols,0,0,sizeof(char)); // 内存能够申请且后面可以释放
theta = (float **)matrix(nrows+2, ncols+2, -1, -1, sizeof(float)); // 内存能够申请但后面不能释放
y = (float **)matrix(nrows+2, ncols+2, -1, -1, sizeof(float)); // 内存能够申请但后面不能释放


if ( row != NULL ) free( row ); // 释放成功
if ( col != NULL ) free( col ); // 释放成功
if ( edgemap != NULL ) free( edgemap ); // 释放成功

if ( theta != NULL ) free( theta ); // 释放失败
if ( y != NULL ) free( y ); // 释放失败

return 0;
}



/* 子函数 */
void **matrix(int nrows, int ncols, int first_row_coord,int first_col_coord, int element_size)
{
void **p;
int alignment;
long i;

if(nrows < 1 || ncols < 1) return(NULL);
i = nrows*sizeof(void *);
/* align the addr of the data to be a multiple of sizeof(long double) */
alignment = i % sizeof(long double);
if(alignment != 0) alignment = sizeof(long double) - alignment;
i += nrows*ncols*element_size+alignment;
if((p = (void **)malloc((size_t)i)) != NULL)
{
/* compute the address of matrix[first_row_coord][0] */
p[0] = (char *)(p+nrows)+alignment-first_col_coord*element_size;
for(i = 1; i < nrows; i++)
/* compute the address of matrix[first_row_coord+i][0] */
p[i] = (char *)(p[i-1])+ncols*element_size;
/* compute the address of matrix[0][0] */
p -= first_row_coord;
}
return(p);
}




...全文
292 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
flamingwolf 2015-05-29
  • 打赏
  • 举报
回复
搞定了 问题出在
p -= first_row_coord;
在子函数内部,P指针移动了 到了主函数内,需要反向移位相同长度才能free掉
赵4老师 2015-05-29
  • 打赏
  • 举报
回复

/*  主程序*/

// matrixleaktest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
//  #include "vld.h"
void myfree(void *p) {
    printf("free %p\n",p);//★★★★★★★★★★★★
    free(p);
}
int _tmain(int argc, _TCHAR* argv[])
{
    int nrows,ncols;
    nrows = 5 ;
    ncols = 3 ;

    float **row, **col,**theta,**y;
    unsigned char  **edgemap;


    /* 源程序提供的内存机制,-1等参数设置存在问题 */
    row = (float **)matrix(nrows, ncols, 0, 0, sizeof(float));      //  内存能够申请且后面可以释放
    col = (float **)matrix(nrows, ncols, 0, 0, sizeof(float));      //  内存能够申请且后面可以释放
    edgemap = (unsigned char **) matrix(nrows,ncols,0,0,sizeof(char));      //  内存能够申请且后面可以释放
    theta = (float **)matrix(nrows+2, ncols+2, -1, -1, sizeof(float));      //  内存能够申请但后面不能释放
    y = (float **)matrix(nrows+2, ncols+2, -1, -1, sizeof(float));      //  内存能够申请但后面不能释放


    if ( row != NULL ) myfree( row );   // 释放成功
    if ( col != NULL ) myfree( col );   // 释放成功
    if ( edgemap != NULL )  myfree( edgemap );   // 释放成功

    if ( theta != NULL )  myfree( theta );   // 释放失败
    if ( y != NULL ) myfree( y );   // 释放失败

    return 0;
}



/*  子函数  */
void **matrix(int nrows, int ncols, int first_row_coord,int first_col_coord, int element_size)
{
  void **p;
  int alignment;
  long i;

  if(nrows < 1 || ncols < 1) return(NULL);
  i = nrows*sizeof(void *);
  /* align the addr of the data to be a multiple of sizeof(long double) */
  alignment = i % sizeof(long double);
  if(alignment != 0) alignment = sizeof(long double) - alignment;
  i += nrows*ncols*element_size+alignment;
  if((p = (void **)malloc((size_t)i)) != NULL)
  {
    printf("malloc return %p\n",p);//★★★★★★★★★★★★
    /* compute the address of matrix[first_row_coord][0] */
    p[0] = (char *)(p+nrows)+alignment-first_col_coord*element_size;
    for(i = 1; i < nrows; i++)
      /* compute the address of matrix[first_row_coord+i][0] */
      p[i] = (char *)(p[i-1])+ncols*element_size;
    /* compute the address of matrix[0][0] */
    p -= first_row_coord;
  }
  return(p);
}

赵4老师 2015-05-29
  • 打赏
  • 举报
回复
free Deallocates or frees a memory block. void free( void *memblock ); Function Required Header Compatibility free <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 None Parameter memblock Previously allocated memory block to be freed Remarks The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc). If memblock is NULL, the pointer is ignored and free immediately returns. Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors. After a memory block has been freed, _heapmin minimizes the amount of free memory on the heap by coalescing the unused regions and releasing them back to the operating system. Freed memory that is not released to the operating system is restored to the free pool and is available for allocation again. When the application is linked with a debug version of the C run-time libraries, free resolves to _free_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 _alloca, calloc, malloc, realloc, _free_dbg, _heapmin
赵4老师 2015-05-29
  • 打赏
  • 举报
回复
matrix函数的实现要求first_row_coord和first_col_coord必须≥0
flamingwolf 2015-05-28
  • 打赏
  • 举报
回复
以下几句貌似不仅仅只是生成一个nrows*ncols的数组

  i = nrows*sizeof(void *);
  /* align the addr of the data to be a multiple of sizeof(long double) */
  alignment = i % sizeof(long double);
  if(alignment != 0) alignment = sizeof(long double) - alignment;
  i += nrows*ncols*element_size+alignment;   //  不仅仅只是得到一大小为nrows*ncols的二维数组
  if((p = (void **)malloc((size_t)i)) != NULL)
fly_dragon_fly 2015-05-28
  • 打赏
  • 举报
回复
分配二级指针,以后要先释放第二级,再free第一级
老王爱上猫 2015-05-28
  • 打赏
  • 举报
回复

 p -= first_row_coord; //你这步啥意思?
赵4老师 2015-05-28
  • 打赏
  • 举报
回复
仅供参考:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
int **newarr2d(int rows,int cols) {
    int **p,i;

    p=(int **)malloc(rows*sizeof(int *));
    if (NULL==p) exit(1);
    for (i=0;i<rows;i++) {
        p[i]=(int *)malloc(cols*sizeof(int));
        if (NULL==p[i]) exit(1);
    }
    return p;
}
void deletearr2d(int **p,int rows) {
    int i;

    for (i=0;i<rows;i++) {
        free(p[i]);
    }
    free(p);
}
int main() {
    int **arr2d,i,j,r,c;

    r=4;
    c=5;
    //在堆中开辟一个4×5的二维int数组
    arr2d=newarr2d(r,c);
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            arr2d[i][j]=i*c+j;
        }
    }
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            printf(" %2d",arr2d[i][j]);
        }
        printf("\n");
    }
    deletearr2d(arr2d,r);

    r=6;
    c=3;
    //在堆中开辟一个6×3的二维int数组
    arr2d=newarr2d(r,c);
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            arr2d[i][j]=i*c+j;
        }
    }
    for (i=0;i<r;i++) {
        for (j=0;j<c;j++) {
            printf(" %2d",arr2d[i][j]);
        }
        printf("\n");
    }
    deletearr2d(arr2d,r);

    return 0;
}
//  0  1  2  3  4
//  5  6  7  8  9
// 10 11 12 13 14
// 15 16 17 18 19
//  0  1  2
//  3  4  5
//  6  7  8
//  9 10 11
// 12 13 14
// 15 16 17
//
flamingwolf 2015-05-28
  • 打赏
  • 举报
回复
大家,保持队形啊,help !

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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