Проблемы с выделением памяти для многомерных массивов в C - PullRequest
0 голосов
/ 14 марта 2012

У меня есть вопрос, касающийся управления памятью в 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 ) );

В конце концов, вот что говорит мне Вальгринд:

==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 очень часто? Любые советы по улучшению этой части кода?

Заранее спасибо

EDIT

Спасибо за быстрые ответы!

Чтобы ответить на вопросы Джорджа

Может быть, я должен написать больше своего кода здесь, чтобы сделать его более понятным, код немного длинный, поэтому я избавляюсь от некоторых вещей, просто чтобы сделать его более понятным.

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

}

Я делаю аналогичные вещи для всех 360 значений par.prueba

Чтобы ответить на вопрос ПолП.Р.О.

Нет, я не освобождаю память. Я делал это раньше, и он рухнул, когда попытался освободить его. Я попробую еще раз посмотреть, если что-то изменится. Я думаю, что моя проблема заключалась в том, чтобы выяснить, когда его освободить.

Чтобы ответить на AoeAoe's

Я думаю, что мой код эквивалентен тому, что вы сделали правильно?

Чтобы ответить на вопрос Криса Лутца.

Я не обязательно хочу выходить при каждом сбое, которое я получаю, но если я позволяю коду работать без выхода, он работает нормально, но затем он случайным образом падает ...

РЕДАКТИРОВАТЬ 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
  }

1 Ответ

1 голос
/ 14 марта 2012

Сначала вам нужно выделить массив для указателей на массивы (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), но вместо того, чтобы иметь двумерный массив целиком, вы получаете один массив, содержащий его вместе (тип **), и несколько массивов (тип *), которые содержат информация хранится в «строке».

Вот пример массива 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]
...