c - C 中多维数组的内存分配问题

标签 c memory malloc memory-leaks valgrind

我有一个关于 C 语言内存管理的问题。

我必须分配一些内存来创建多维数组,所以我使用 malloc。例如这里:

par.prueba[0][0] = (int *)malloc( 4 * sizeof ( int ) );

其中一些我必须在循环内动态分配内存,如下所示:

for(;j<=par.param1[0][0];j++){

 pj = -Np * cP + (j - 1) * cP; //aquí va de -NpcP hasta NpcP


 par.prueba[0][j-1][2] = floor((Cx + pj) * par.Bn + 0.5) + par.Bn/2; //xb

 if(j!=par.param1[0][0])
 par.prueba[0][j] = (int *)malloc( 4 * sizeof ( int ) );
}

我的代码中有几行这样的代码。我还检查分配是否像这样工作:

if(par.prueba[0][0]==NULL){
  printf("Fail\n");
  exit(2);
}

问题是有时 malloc 无法分配所请求的内存,因此我的程序退出。每次我再次编译和运行时它都存在于不同的地方。如果我不检查分配的空间,我的程序运行没有问题,但最终崩溃。

我使用 valgrind 尝试查找问题,但遇到很多此类错误:

5,080 bytes in 5 blocks are possibly lost in loss record 5,640 of 5,670

错误通常会追溯到类似这样的行

    par.prueba[0][0] = (int *)malloc( 4 * sizeof ( int ) );

最后,这就是 valgrind 告诉我的:

==13628== LEAK SUMMARY:
==13628==    definitely lost: 2,856 bytes in 10 blocks
==13628==    indirectly lost: 10,120 bytes in 505 blocks
==13628==      possibly lost: 614,134 bytes in 6,119 blocks
==13628==    still reachable: 497,948 bytes in 6,432 blocks
==13628==         suppressed: 0 bytes in 0 blocks

所以我很确定我没有内存不足,但我遇到了很多内存泄漏。我的问题是,我做错了什么?我正确使用了 malloc 吗?如此频繁地使用 malloc 是否有问题?有什么建议可以改进这部分代码吗?

提前致谢

编辑

感谢您的快速解答!

回答乔治的问题

也许我应该在这里写更多代码以使其更清晰,代码有点长,因此我省略了一些内容以使其更清晰。

prueba[0][0] 在该循环之前初始化。问题是我的代码中有几个这样的循环,但我很确定我初始化了所有值。这是代码

我首先声明一个这样的结构

typedef struct parametros{
  int cT;
  float Bn;
  int **prueba[360];
  int param1[360][3];
  int ***pixels[360];
} 

struct parametros par;

然后我就这样使用

par.param1[0][0] = 2*Np + 1; //Np is initialized before

par.prueba[0] = (int **)malloc( par.param1[0][0]* sizeof ( int * ) );

if(par.prueba[0]==NULL){
  printf("Fail\n");
  exit(2);
}

par.prueba[0][0] = (int *)malloc( 4 * sizeof ( int ) );

if(par.prueba[0][0]==NULL){
  printf("Fail\n");
  exit(2);
}

然后我像这样向数组分配一些值

par.prueba[0][0][1] = floor(Nhe/par.cT);//Nhe and par.cT are initialized before

par.prueba[0][0][0] = -par.prueba[0][0][1];

par.param1[0][1] = 0; 

par.param1[0][2] = par.cT * par.Bn; //par.Bn is also initialized before


par.prueba[0][0][3] = floor((Cy + par.prueba[0][0][0] * par.cT) * par.Bn + 0.5) + par.Bn/2; //Cy is initialized before

然后是循环

int j = 1;
for(;j<=par.param1[0][0];j++){

   pj = -Np * cP + (j - 1) * cP; //cP is initialized before and pj is declared before

   par.prueba[0][j-1][2] = floor((Cx + pj) * par.Bn + 0.5) + par.Bn/2; //xb

   if(j!=par.param1[0][0]){
  par.prueba[0][j] = (int *)malloc( 4 * sizeof ( int ) );

      if(par.prueba[0][j]==NULL){
    printf("Fail\n");
    exit(2);
      }
    }

}

我对 par.prueba 的所有 360 个值做了类似的事情

回答 PaulP.R.O. 的问题。

不,我不释放内存。我以前这样做过,当我尝试释放它时它崩溃了。我会再次尝试看看是否有变化。我认为我的问题是试图弄清楚何时释放它。

回答AoeAoe的

我认为我的代码相当于你做对的事情?

回答 Chris Lutz 的问题。

我不一定要在遇到每次失败时退出,但如果我让代码运行而不退出,它会运行良好,但随后会随机崩溃......

编辑2

在使用完“数组”后,我添加了释放内存的代码,并且由于无法使用 malloc 分配一些内存而存在同样的问题

for(y=0;y<360;y++){

   for(t=0;t<par.param1[y][0];t++){

   free(par.prueba[y][t]);

   }

   free(par.prueba[y]);

}

编辑3——完整代码

好的,这是完整的代码,如果有点困惑,抱歉。如果需要的话我会解释的。基本上我需要多维数组来存储一些参数,然后我将使用一些图像的像素值来计算一些东西。代码尚未完成,但我试图测试它如何处理所有动态分配的内存。这段代码编译没有问题,并且如果我在使用 malloc 后不检查内存分配,那么首先运行也不会出现问题。但一旦我开始使用该程序,它就会随机崩溃。

#include <stdio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <magick/MagickCore.h>

void ClickCallback(GtkWidget *widget, GdkEventButton *event, gpointer callback_data);
void computar_transformadas(GtkWidget *widget, GdkEventButton *event, gpointer callback_data);
void ext_parametros(GtkImage *img);
static void destroy_event(GtkWidget *widget, gpointer data);
static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data);
void suma(int** trazo,int o,int entra);

GtkWidget *window, *caja, *button1, *button2, *file_selection_box;
GtkImage *imagen = NULL;
GdkPixbuf *pixbuf = NULL;
guchar *pixs = NULL;
guchar *p = NULL;
int rowstride, n_channels;

typedef struct parametros{
   int cT;
   float Bn;
   int **prueba[360];
   int param1[360][3];
   int ***pixels[360];
};

struct parametros par;

int main (int argc, char *argv[]){

  /*--  Initialize GTK --*/
  gtk_init (&argc, &argv);

  /*-- Create the new window --*/
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  button1 = gtk_button_new_with_label("Abrir.");
  button2 = gtk_button_new_with_label("Analizar.");

  caja = gtk_vbox_new(0,0);


  gtk_window_set_default_size(window,200,200);

  /*-- Agrega funcionalidad al botón -- */
  g_signal_connect(G_OBJECT(button1), "button_press_event", G_CALLBACK(ClickCallback), NULL);

  /*-- Agrega funcionalidad al botón -- */
  g_signal_connect(G_OBJECT(button2), "button_press_event", G_CALLBACK(computar_transformadas), NULL);


  /*-- Agrega el botón a la ventana -- */
  gtk_container_add(GTK_CONTAINER(window), caja);


  gtk_box_pack_end(caja,button1,FALSE,FALSE,1);
  gtk_box_pack_end(caja,button2,FALSE,FALSE,1);

  /*-- Display the window con el botón --*/
  gtk_widget_show_all(window);

  /*-- Start the GTK event loop --*/
  gtk_main();

  /* -- Cierra los eventos -- */
  g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
  g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy_event), NULL);


  /*-- Return 0 if exit is successful --*/
  return 0;

}


void open_file(char *file){


  if(imagen != NULL)
    gtk_image_clear(imagen);


  imagen = gtk_image_new_from_file(file);

  gtk_box_pack_end(caja,imagen,FALSE,FALSE,1);

  gtk_widget_show_all(window);

  ext_parametros(imagen);

}

void ext_parametros(GtkImage *img){


  pixbuf = gtk_image_get_pixbuf(img);

  n_channels = gdk_pixbuf_get_n_channels(pixbuf);
  pixs=gdk_pixbuf_get_pixels(pixbuf);
  p=gdk_pixbuf_get_pixels(pixbuf);
  rowstride=gdk_pixbuf_get_rowstride(pixbuf);

  int pT = 1;

  int pj;

  int M = gdk_pixbuf_get_width(pixbuf);
  int N = gdk_pixbuf_get_height(pixbuf);

  int cP = 1; //paso en P
  par.cT = 1;

  par.Bn = pow(2,12); //division de cada pixel

  float Cx = (float) (M-1)/2; //centro de la imagen eje x
  float Cy = (float) (N-1)/2; //centro de la imagen eje y

  float Mh = Cx + 0.5; //pixel central
  float Nh = Cy + 0.5; //pixel central

  double Pmax = pow((pow(Mh,2)+pow(Nh,2)),0.5)-0.001;

  double E = (1/(2*par.Bn))*(((2*Pmax)/pT)+1);

  double Mhe = Mh - E; //largo tomando en cuenta el error

  double Nhe = Nh - E; //ancho tomando en cuenta el error

  int MBn = M * par.Bn;

  int NBn = N * par.Bn;


  /*  φ = 0  */

  int Np = floor(Mhe/cP);

  par.param1[0][0] = 2*Np + 1; //NP

  par.prueba[0] = (int **)malloc( par.param1[0][0]* sizeof ( int * ) );

  if(par.prueba[0]==NULL){
  printf("¡Fallo al asignar memoria! 0\n");
  exit(2);
  }

  par.prueba[0][0] = (int *)malloc( 4 * sizeof ( int ) );

  if(par.prueba[0][0]==NULL){
  printf("¡Fallo al asignar memoria! 0\n");
  exit(2);
  }

  par.prueba[0][0][1] = floor(Nhe/par.cT);//tend
  par.prueba[0][0][0] = -par.prueba[0][0][1];//tbegin

  par.param1[0][1] = 0; //xinc

  par.param1[0][2] = par.cT * par.Bn; //yinc

  par.prueba[0][0][3] = floor((Cy + par.prueba[0][0][0] * par.cT) * par.Bn + 0.5) + par.Bn/2; //yb

  //------------ -NpcP < p < NpcP ----------------//


  int j = 1;
  for(;j<=par.param1[0][0];j++){

 pj = -Np * cP + (j - 1) * cP; //aquí va de -NpcP hasta NpcP

 par.prueba[0][j-1][2] = floor((Cx + pj) * par.Bn + 0.5) + par.Bn/2; //xb

 if(j!=par.param1[0][0]){
     par.prueba[0][j] = (int *)malloc( 4 * sizeof ( int ) );

     if(par.prueba[0][j]==NULL){
           printf("¡Fallo al asignar memoria! 0 %d\n",j);
       exit(2);
         }
 }

   }

   //----------- Precomputar y calcular 0 < φ < 90 --------------//

   int phi = 1;
   double t1x;
   double t1y;
   double t2x;
   double t2y;




   for(;phi<90;phi++){
  Pmax = Mhe * fabs(cos(phi)) + Nhe * fabs(sin(phi));

  Np = floor(Pmax/cP);

  par.param1[phi][0] = 2 * Np + 1; //NP

  par.prueba[phi] = (int **)malloc( par.param1[phi][0]* sizeof ( int * ) );

  if(par.prueba[phi]==NULL){
     printf("¡Fallo al asignar memoria! %d\n",phi);
     exit(2);
  }

  par.prueba[phi][0] = (int *)malloc( 4 * sizeof ( int ) );

  if(par.prueba[phi][0]==NULL){
      printf("¡Fallo al asignar memoria! %d\n",phi);
      exit(2);
  }


  par.param1[phi][1] = -par.cT*sin(phi)*par.Bn; //xinc
  par.param1[phi][2] = par.cT*cos(phi)*par.Bn; //yinc

  for(j=1;j<=par.param1[phi][0];j++){

      pj = -Np * cP + (j - 1) * cP;

      t1y = -((Mhe - (pj * cos(phi)))/sin(phi));
      t1x = -((Nhe + (pj * sin(phi)))/cos(phi));
      t2y = ((Mhe + (pj * cos(phi)))/sin(phi));
      t2x = ((Nhe - (pj * sin(phi)))/cos(phi));

      par.prueba[phi][j-1][0] = ceil(fmax(t1y,t1x)/par.cT); //tbegin
      par.prueba[phi][j-1][1] = floor(fmin(t2y,t2x)/par.cT); //tend

      par.prueba[phi][j-1][2] = floor((Cx + pj * cos(phi)) * par.Bn + 0.5 + (par.param1[phi][1] * par.prueba[phi][j-1][0])) + par.Bn/2; //xb
      par.prueba[phi][j-1][3] = floor((Cy + pj * sin(phi)) * par.Bn + 0.5 + (par.param1[phi][2] * par.prueba[phi][j-1][0])) + par.Bn/2; //yb

      if(j!=par.param1[phi][0]){
          par.prueba[phi][j] = (int *)malloc( 4 * sizeof ( int ) );

          if(par.prueba[phi][j]==NULL){
            printf("¡Fallo al asignar memoria! %d %d\n",phi,j);
            exit(2);
          }
      }

   }

    }

    //----------- Precomputar φ = 90 --------------//

    int tendbeg;

    Np = floor(Nhe/cP);

    par.param1[90][0] = 2 * Np + 1; //NP

    par.prueba[90] = (int **)malloc( par.param1[90][0]* sizeof ( int * ) );

    if(par.prueba[90]==NULL){
     printf("¡Fallo al asignar memoria! 90\n");
     exit(2);
    }

    par.prueba[90][0] = (int *)malloc( 4 * sizeof ( int ) );

    if(par.prueba[90][0]==NULL){
    printf("¡Fallo al asignar memoria! 90\n");
    exit(2);
    }


    par.prueba[90][0][1] = floor(Mhe/par.cT); //tend

    par.prueba[90][0][0] = -par.prueba[90][0][1]; //tbegin

    tendbeg = par.prueba[90][0][1] - par.prueba[90][0][0];

    par.param1[90][1] = -par.cT * par.Bn; //xinc

    par.param1[90][2] = 0; //yinc

    par.prueba[90][0][2] = floor(Cx * par.Bn + par.param1[90][1] * par.prueba[90][0][0] + 0.5) + par.param1[90][1] * par.Bn + par.Bn/2; //xb

    //----------- Calcular φ = 90 --------------//

    for(j=1;j<=par.param1[90][0];j++){

     pj = -Np * cP + (j - 1) * cP; //aquí va de -NpcP hasta NpcP

     par.prueba[90][j-1][3] = floor((Cy + pj) * par.Bn + 0.5) + par.Bn/2; //se guarda cada valor de cada línea //yb

     if(j!=par.param1[90][0]){
     par.prueba[90][j] = (int *)malloc( 4 * sizeof ( int ) );

     if(par.prueba[90][j]==NULL){
        printf("¡Fallo al asignar memoria! 90 %d\n",j);
        exit(2);
     }
      }

     }

     //----------- Precomputar y calcular 90 < φ < 180 --------------//

     phi = 91;

     for(;phi<180;phi++){
     Pmax = Mhe * fabs(cos(phi)) + Nhe * fabs(sin(phi));

     Np = floor(Pmax/cP);

     par.param1[phi][0] = 2 * Np + 1; //NP

     par.prueba[phi] = (int **)malloc( par.param1[phi][0]* sizeof ( int * ) );

     if(par.prueba[phi]==NULL){
    printf("¡Fallo al asignar memoria! %d\n",phi);
    exit(2);
     }

         par.prueba[phi][0] = (int *)malloc( 4 * sizeof ( int ) );

         if(par.prueba[phi][0]==NULL){
           printf("¡Fallo al asignar memoria! %d\n",phi);
           exit(2);
         }

     par.param1[phi][1] = -(par.cT*sin(phi)*par.Bn); //xinc
     par.param1[phi][2] = par.cT*cos(phi)*par.Bn; //yinc

     for(j=1;j<=par.param1[phi][0];j++){

      pj = -Np * cP + (j - 1) * cP;

      t1y = -((Mhe - (pj * cos(phi)))/sin(phi));
      t1x = ((Nhe - (pj * sin(phi)))/cos(phi));
      t2y = ((Mhe + (pj * cos(phi)))/sin(phi));
      t2x = -((Nhe + (pj * sin(phi)))/cos(phi));

      par.prueba[phi][j-1][0] = ceil(fmax(t1y,t1x)/par.cT); //tbegin
      par.prueba[phi][j-1][1] = floor(fmin(t2y,t2x)/par.cT); //tend

      par.prueba[phi][j-1][2] = floor((Cx + pj * cos(phi)) * par.Bn + 0.5 + (par.param1[phi-1][1] * par.prueba[phi][j-1][0])) + par.Bn/2; //xb
      par.prueba[phi][j-1][3] = floor((Cy + pj * sin(phi)) * par.Bn + 0.5 + (par.param1[phi-1][2] * par.prueba[phi][j-1][0])) + par.Bn/2; //yb

      if(j!=par.param1[phi][0]){
        par.prueba[phi][j] = (int *)malloc( 4 * sizeof ( int ) );

        if(par.prueba[phi][j]==NULL){
            printf("¡Fallo al asignar memoria! %d %d\n",phi,j);
            exit(2);
        }
      }


  }

    }

    //----------- Precomputar φ = 180 --------------//

    Np = floor(Mhe/cP);

    par.param1[180][0] = 2*Np + 1; //NP de 0 grados

    par.prueba[180] = (int **)malloc( par.param1[180][0]* sizeof ( int * ) );

    if(par.prueba[180]==NULL){
    printf("¡Fallo al asignar memoria! 180\n");
    exit(2);
    }

    par.prueba[180][0] = (int *)malloc( 4 * sizeof ( int ) );

    if(par.prueba[180][0]==NULL){
    printf("¡Fallo al asignar memoria! 180\n");
    exit(2);
    }

    par.prueba[180][0][0] = -floor(Nhe/par.cT); //tbegin  //-tend de 0 grados

    par.prueba[180][0][1] = -par.prueba[180][0][0]; //tend  //-tbegin de 0 grados

    par.param1[180][1] = 0; //xinc

    par.param1[180][2] = -(par.cT * par.Bn); //yinc

    par.prueba[180][0][3] = floor((Cy - par.prueba[180][0][0] * par.cT) * par.Bn + 0.5) + par.Bn/2; //yb

    //------------ Calcular φ = 180 ----------------//


    for(j=1;j<=par.param1[180][0];j++){

    pj = -Np * cP + (j - 1) * cP; //aquí va de -NpcP hasta NpcP

    par.prueba[180][j-1][2] = floor((Cx - pj) * par.Bn + 0.5) + par.Bn/2; //se guarda cada valor de cada línea //xb

    if(j!=par.param1[180][0]){
    par.prueba[180][j] = (int *)malloc( 4 * sizeof ( int ) );

    if(par.prueba[180][j]==NULL){
        printf("¡Fallo al asignar memoria! 180 %d\n",j);
        exit(2);
    }
    }
    }

    //----------- Precomputar y calcular 180 < φ < 270 --------------//

   phi = 181;

   for(;phi<270;phi++){
  Pmax = Mhe * fabs(cos(phi)) + Nhe * fabs(sin(phi));

  Np = floor(Pmax/cP);

  par.param1[phi][0] = 2 * Np + 1; //NP

  par.prueba[phi] = (int **)malloc( par.param1[phi][0]* sizeof ( int * ) );

  if(par.prueba[phi]==NULL){
    printf("¡Fallo al asignar memoria! %d\n",phi);
    exit(2);
  }

  par.prueba[phi][0] = (int *)malloc( 4 * sizeof ( int ) );

  if(par.prueba[phi][0]==NULL){
    printf("¡Fallo al asignar memoria! %d 0\n",phi);
    exit(2);
  }

  par.param1[phi][1] = -(par.cT*sin(phi)*par.Bn); //xinc
  par.param1[phi][2] = par.cT*cos(phi)*par.Bn; //yinc

  for(j=1;j<=par.param1[phi][0];j++){

      pj = -Np * cP + (j - 1) * cP;

      t1y = ((Mhe + (pj * cos(phi)))/sin(phi));
      t1x = ((Nhe - (pj * sin(phi)))/cos(phi));
      t2y = -((Mhe - (pj * cos(phi)))/sin(phi));
      t2x = -((Nhe + (pj * sin(phi)))/cos(phi));

      par.prueba[phi][j-1][0] = ceil(fmax(t1y,t1x)/par.cT); //tbegin
      par.prueba[phi][j-1][1] = floor(fmin(t2y,t2x)/par.cT); //tend

      par.prueba[phi][j-1][2] = floor((Cx + pj * cos(phi)) * par.Bn + 0.5 + (par.param1[phi-1][1] * par.prueba[phi][j-1][0])) + par.Bn/2; //xb
      par.prueba[phi][j-1][3] = floor((Cy + pj * sin(phi)) * par.Bn + 0.5 + (par.param1[phi-1][2] * par.prueba[phi][j-1][0])) + par.Bn/2; //yb

      if(j!=par.param1[phi][0]){
          par.prueba[phi][j] = (int *)malloc( 4 * sizeof ( int ) );

          if(par.prueba[phi][j]==NULL){
            printf("¡Fallo al asignar memoria! %d %d\n",phi,j);
            exit(2);
          }
      }


  }

   }

   //----------- Precomputar φ = 270 --------------//

   Np = floor(Nhe/cP);

   par.param1[270][0] = 2 * Np + 1; //NP //NP del angulo de 90 param1[90][0]

   par.prueba[270] = (int **)malloc( par.param1[270][0]* sizeof ( int * ) );

   if(par.prueba[270]==NULL){
printf("¡Fallo al asignar memoria! 270\n");
exit(2);
   }

   par.prueba[270][0] = (int *)malloc( 4 * sizeof ( int ) );

   if(par.prueba[270][0]==NULL){
 printf("¡Fallo al asignar memoria! 270\n");
 exit(2);
   }

   par.prueba[270][0][1] = floor(Mhe/par.cT); //tend //-tbegin del angulo de 90

   par.prueba[270][0][0] = -par.prueba[270][0][1]; //tbegin //-tend del angulo de 90

   par.param1[270][1] = par.cT * par.Bn; //xinc

   par.param1[270][2] = 0; //yinc

   par.prueba[270][0][2] = floor(Cx * par.Bn + par.param1[270][1] * par.prueba[270][0][0] + 0.5) + par.Bn/2; //xb

   //----------- Calcular φ = 270 --------------//

   for(j=1;j<=par.param1[270][0];j++){

   pj = -Np * cP + (j - 1) * cP; //aquí va de -NpcP hasta NpcP

   par.prueba[270][j-1][3] = floor((Cy - pj) * par.Bn + 0.5) + par.Bn/2; //se guarda cada valor de cada línea //yb

   if(j!=par.param1[270][0]){
     par.prueba[270][j] = (int *)malloc( 4 * sizeof ( int ) );

     if(par.prueba[270][j]==NULL){
        printf("¡Fallo al asignar memoria! 270 %d\n",j);
        exit(2);
     }
   }
   }


   //----------- Precomputar y calcular 270 < φ < 360 --------------//


   for(;phi<360;phi++){
   Pmax = Mhe * fabs(cos(phi)) + Nhe * fabs(sin(phi));

   Np = floor(Pmax/cP);

   par.param1[phi][0] = 2 * Np + 1; //NP

   par.prueba[phi] = (int **)malloc( par.param1[phi][0]* sizeof ( int * ) );

   if(par.prueba[phi]==NULL){
    printf("¡Fallo al asignar memoria! %d\n",phi);
    exit(2);
   }

   par.prueba[phi][0] = (int *)malloc( 4 * sizeof ( int ) );

   if(par.prueba[phi][0]==NULL){
    printf("¡Fallo al asignar memoria! %d\n",phi);
    exit(2);
   }


   par.param1[phi][1] = -(par.cT*sin(phi)*par.Bn); //xinc
   par.param1[phi][2] = par.cT*cos(phi)*par.Bn; //yinc

   for(j=1;j<=par.param1[phi][0];j++){

      pj = -Np * cP + (j - 1) * cP;

      t1y = (Mhe + (pj * cos(phi)))/sin(phi);
      t1x = -((Nhe + (pj * sin(phi)))/cos(phi));
      t2y = -((Mhe - (pj * cos(phi)))/sin(phi));
      t2x = (Nhe - (pj * sin(phi)))/cos(phi);

      par.prueba[phi][j-1][0] = ceil(fmax(t1y,t1x)/par.cT); //tbegin
      par.prueba[phi][j-1][1] = floor(fmin(t2y,t2x)/par.cT); //tend

      par.prueba[phi][j-1][2] = floor((Cx + pj * cos(phi)) * par.Bn + 0.5 + (par.param1[phi-1][1] * par.prueba[phi][j-1][0])) + par.Bn/2; //xb
      par.prueba[phi][j-1][3] = floor((Cy + pj * sin(phi)) * par.Bn + 0.5 + (par.param1[phi-1][2] * par.prueba[phi][j-1][0])) + par.Bn/2; //yb

      if(j!=par.param1[phi][0]){
          par.prueba[phi][j] = (int *)malloc( 4 * sizeof ( int ) );

          if(par.prueba[phi][j]==NULL){
            printf("¡Fallo al asignar memoria! %d %d\n",phi,j);
            exit(2);
          }
      }


  }

   }


 }

 void computar_transformadas(GtkWidget *widget, GdkEventButton *event, gpointer callback_data){

int tendbegin;
int xi;
int yi;
    int ti;
int phi;
int j;
int o;
int sale=0;//variable para salir del for de tendbegin en los casos especiales
int entra = 0;

for(phi = 0; phi < 360;phi++){ //todos los ángulos
    e = par.cT;

    sale = 0;

    par.pixels[phi] = (int ***)malloc( par.param1[phi][0]* sizeof ( int ** ) );

    if(par.pixels[phi]==NULL){
        printf("¡Fallo al asignar memoria! (pixels) %d\n",phi);
        exit(2);
    }


    for(j=0; (sale != 1); j++){  //todas las líneas

         tendbegin = par.prueba[phi][j][1]-par.prueba[phi][j][0];

             par.pixels[phi][j] = (int **)malloc( tendbegin * sizeof ( int * ) );

         if(par.pixels[phi][j]==NULL){
        printf("¡Fallo al asignar memoria! (pixels) %d %d\n",phi,j);
        exit(2);
         }


         if(phi==0 || phi==90 || phi==180 || phi==270 || phi==360 || j==(par.param1[phi][0]-1)){
          sale = 1;
         }

         entra=0;

         for(o=0; o < tendbegin;o++){ 

        par.pixels[phi][j][o] = (int *)malloc( 2 * sizeof ( int ) );

        if(par.pixels[phi][j][o]==NULL){
                printf("¡Fallo al asignar memoria! (pixels) %d %d %d\n",phi,j,o);
            exit(2);
        }

        ti = (par.prueba[phi][j][0] + o)*par.cT;

        xi = par.prueba[phi][j][2] + floor(o*par.param1[phi][1]);
        yi = par.prueba[phi][j][3] + floor(o*par.param1[phi][2]);

        par.pixels[phi][j][o][0] = floor(xi/par.Bn);//ii//para enviarlos a las funcionales se guardan en matriz
        par.pixels[phi][j][o][1] = floor(yi/par.Bn);//ji

        if(o == (tendbegin/2)){
          entra=1;
        }

        if(o==tendbegin-1){
          suma(par.pixels[phi][j],o, entra);

        }


         }


        }
   }


int y;
int t;
int p;

for(y=0;y<360;y++){

  for(t=0;t<par.param1[y][0];t++){


      free(par.prueba[y][t]);

      for(p=0;p<4;p++){
         free(par.pixels[y][t][p]);
      }


      free(par.pixels[y][t]);


  }

  free(par.prueba[y]);
  free(par.pixels[y]);

    }


gdk_pixbuf_save(pixbuf,"/path/to/image/prueba.png","png",NULL,NULL);



 }

 void suma(int** trazo,int o,int entra){

int i;
int gris;
int temp=0;

for(i=0;i<o;i++){

    p = pixs + trazo[i][1]/*y*/ * rowstride + trazo[i][0]/*x*/ * n_channels;//para colocarse en la imagen
    gris=0.2989 * p[0] + 0.5870 * p[1] + 0.1140 * p[2]; //para transofrmar de RGB a escala de gris

    if(entra ==1){
     p[0]=(guchar)50;
     p[1]=(guchar)0;
     p[2]=(guchar)0;
     }

     entra = 0;


     temp=rowstride;

     }

 }

  void ClickCallback(GtkWidget *widget, GdkEventButton *event, gpointer callback_data)
  {
/*-- Create the selector widget --*/
file_selection_box = gtk_file_chooser_dialog_new("Porfavor seleccione un archivo.",NULL,GTK_FILE_CHOOSER_ACTION_OPEN,GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);


if (gtk_dialog_run (GTK_DIALOG (file_selection_box)) == GTK_RESPONSE_ACCEPT)
   {
     // char *filename;
      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_selection_box));
      open_file(filename);
      g_free (filename);
}
gtk_widget_destroy (file_selection_box);
  }

  static void destroy_event(GtkWidget *widget, gpointer data)
  {
   gtk_main_quit();
  }

  static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
  {
   return FALSE; // must return false to trigger destroy event for window
  }

最佳答案

首先,您需要为指向数组的指针(char **)分配数组,然后需要逐一分配每个“行”。

int **array = malloc(nrows * sizeof(int *));
assert(array);
for (int i=0; i < nrows; i++)
{
    array[i]= malloc(nbars * sizeof(int));
    assert(array[i]);
}

要释放,您需要向后执行此操作,例如释放每一行,然后释放指针数组:

for (int i=0; i < nrows; i++)
    free(array[i]);

free(array);

基本上,这些并不是真正的“真正的数组”(根据 C 定义),但不是将 2D 数组作为一个整体,而是一个将其组合在一起的数组(类型 **)和多个(类型 *)数组信息存储在“行”中。

这是 3x3 数组的示例,--> 代表(指向)。

a[0] --> b[0],b[1],b[2]
a[1] --> c[0],c[1],c[2]
a[2] --> d[0],d[1],d[2]

关于c - C 中多维数组的内存分配问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9707382/

相关文章:

c - 为什么 scanf 不读取 int 的缓冲输入?

java - Java中如何确定对象的大小

c - sprintf 和分配内存

c - 在 C 中使用指针通过引用修改数组

c - 为什么C头文件中同名的函数声明和函数定义可以(来自redis源码)

c++ - 读取文件而不是将其作为参数传递

memory - x86 内存排序 : Loads Reordered with Earlier Stores vs. 处理器内转发

c: free() - glibc 无效指针

c++ - 编译器是否有可能检测到整数溢出或其他数据类型溢出的可能性?

ios - 为什么iOS BLE通信时会出现这么多NSNotification,如何释放?