我有一个关于 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/