Code Bye

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

 

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

/*  主程序*/

// 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);
}
5分
 p -= first_row_coord; //你这步啥意思?
分配二级指针,以后要先释放第二级,再free第一级
大家,保持队形啊,help !
15分
仅供参考:
#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
//
以下几句貌似不仅仅只是生成一个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)
matrix函数的实现要求first_row_coord和first_col_coord必须≥0
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

/*  主程序*/

// 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);
}

搞定了
问题出在
p -= first_row_coord;

在子函数内部,P指针移动了
到了主函数内,需要反向移位相同长度才能free掉


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明关于内存分配和指针移动,请教大家