繁体   English   中英

在未初始化的指针上使用 Malloc/Realloc 时出现段错误

[英]SegFault while using Malloc/Realloc on an uninitialized pointer

我正在开发一个“轻型无人机模拟器”(在 C 中),我的任务之一是在我左键单击 map 时添加一个 static 目标。到目前为止一切顺利。 问题是,我不想创建一个具有给定大小的矩阵作为全局变量,而是想从一个未初始化的指针指针开始,一旦我左键单击,我就会重新分配新的 memory,以便始终有足够的 memory 可用但不会更多. 另外,我的“矩阵”应该有 4 列用于 3D 坐标,1 列用于“激活”。

这是我的代码的一部分:

/* Main program */

double **TargetsArray;

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

/* Call of model-specific mouse handling function */
   HandleSpecialMouseEvent(button, state, x, y, &ActualFlockingParams,
            &ActualVizParams, TargetPosition, TargetsArray, Modder);
}
void HandleSpecialMouseEvent(int button,
        int state,
        int x,
        int y,
        flocking_model_params_t * FlockingParams,
        vizmode_params_t * VizParams, 
        double * CoordTarg, double ** TargetsArray,
        const int Modifier) {

       static int cnt = 0;

       if (button == GLUT_LEFT && state == GLUT_DOWN && Modifier == GLUT_ACTIVE_ALT) {
            FillVect(CoordTarg, MouseCoordToReal_2D(x, VizParams->MapSizeXY,
                    VizParams->Resolution) + VizParams->CenterX, -MouseCoordToReal_2D(y, VizParams->MapSizeXY,
                    VizParams->Resolution) + VizParams->CenterY, 0);
            printf("%d\n", cnt);

            if (cnt == 0) {

                TargetsArray = malloc( sizeof *TargetsArray );
                TargetsArray[cnt] = malloc( sizeof **TargetsArray * 4);
                printf("Hello");
                TargetsArray[cnt][0] = CoordTarg[0];
                TargetsArray[cnt][1] = CoordTarg[1];
                TargetsArray[cnt][2] = 0;
                TargetsArray[cnt][3] = 1;

                cnt += 1;
            }
            else {
                printf("Youhou");
                TargetsArray = realloc(TargetsArray, sizeof *TargetsArray * (cnt + 1) );
                TargetsArray[cnt] = malloc( sizeof **TargetsArray * 4);
                TargetsArray[cnt][0] = CoordTarg[0];
                TargetsArray[cnt][1] = CoordTarg[1];
                TargetsArray[cnt][2] = 0;
                TargetsArray[cnt][3] = 1;
                TargetsArray[cnt - 1][3] = 0;

                cnt += 1;

            }

            // for (int j = 0; j < cnt; j++) {
            //     for (int i = 0; i < 4; i++) {
            //         printf("%f\t", TargetsArray[j][i]);
            //     }
            //     printf("\n");
            // }
        }


}

我通常会遇到两种类型的错误:

0
Hello1
Youhou2
Erreur de segmentation (core dumped)

OR 

0
Hello1
free(): invalid next size (fast)
Abandon (core dumped)

我知道有更简单的方法可以做到这一点,但我真的很想了解为什么这不起作用。 我很确定这是由于我使用mallocrealloc的方式,但我也不明白为什么在第一个“循环”中程序没有将 go 放入 if 语句中,而它打印“0”然后为什么它在打印计数器(cnt)之前打印“Hello”?

我希望我为您提供了足够的代码来理解我的问题,但如果缺少某些内容,请告诉我。

谢谢 !!

关于malloc和realloc, please check the lines about malloc, please check the memory is available and could be allocated, 都返回NULL以防错误。

只需检查是否有足够的 memory,并且可以分配给两个 alloc 调用,如下所示:

TargetsArray = malloc( sizeof *TargetsArray );
if(TargetsArray  == NULL){
//oh! not enough mem, or whatever...
}
//...
void* TargetsArray_ra = realloc(TargetsArray, sizeof(*TargetsArray) * (cnt + 1) );
if(TargetsArray_ra == NULL){
//oh! could not realloc
//if you wish to return, don't forget to free up the TargetsArray 
if(TargetsArray != NULL){free(TargetsArray);TargetsArray=NULL;}
//return;
}else{//when realloc was success
TargetsArray = TargetsArray_ra ;
}

同样检查TargetsArray[cnt] = malloc( sizeof **TargetsArray * 4); , 在访问它之前确保它需要一个正确的非NULL ptr

那些 if-else 块也有点相同,除了最后一个语句,除此之外当你调试代码时,你在哪一行得到段错误? 您确定传递的CoordTarg不是NULL并且长度合适? FillVect函数呢? 它按预期工作吗?

您需要更改函数的参数TargetsArray ,以便它指向全局变量,而不仅仅是存储相同的值。

主要程序:

double **TargetsArray;

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

/* Call of model-specific mouse handling function */
   HandleSpecialMouseEvent(button, state, x, y, &ActualFlockingParams,
            &ActualVizParams, TargetPosition, &TargetsArray, Modder);
}
void HandleSpecialMouseEvent(int button,
        int state,
        int x,
        int y,
        flocking_model_params_t * FlockingParams,
        vizmode_params_t * VizParams, 
        double * CoordTarg, double *** TargetsArray,
        const int Modifier) {

       static int cnt = 0;

       if (button == GLUT_LEFT && state == GLUT_DOWN && Modifier == GLUT_ACTIVE_ALT) {
            FillVect(CoordTarg, MouseCoordToReal_2D(x, VizParams->MapSizeXY,
                    VizParams->Resolution) + VizParams->CenterX, -MouseCoordToReal_2D(y, VizParams->MapSizeXY,
                    VizParams->Resolution) + VizParams->CenterY, 0);
            printf("%d\n", cnt);

            if (cnt == 0) {

                *TargetsArray = malloc( sizeof **TargetsArray );
                (*TargetsArray)[cnt] = malloc( sizeof ***TargetsArray * 4);
                printf("Hello\n");
                (*TargetsArray)[cnt][0] = CoordTarg[0];
                (*TargetsArray)[cnt][1] = CoordTarg[1];
                (*TargetsArray)[cnt][2] = 0;
                (*TargetsArray)[cnt][3] = 1;

                cnt += 1;
            }
            else {
                printf("Youhou");
                *TargetsArray = realloc(*TargetsArray, sizeof **TargetsArray * (cnt + 1) );
                (*TargetsArray)[cnt] = malloc( sizeof ***TargetsArray * 4);
                (*TargetsArray)[cnt][0] = CoordTarg[0];
                (*TargetsArray)[cnt][1] = CoordTarg[1];
                (*TargetsArray)[cnt][2] = 0;
                (*TargetsArray)[cnt][3] = 1;
                (*TargetsArray)[cnt - 1][3] = 0;

                cnt += 1;

            }

            // for (int j = 0; j < cnt; j++) {
            //     for (int i = 0; i < 4; i++) {
            //         printf("%f\t", *TargetsArray[j][i]);
            //     }
            //     printf("\n");
            // }
        }


}

注意:括号非常重要

每次重新分配 memory 时,都会在 TargetsArray 中存储一个新的TargetsArray地址。 由于您正在更改 function 中的值,因此您需要为 function 提供变量TargetsArray的地址。 其他方式,您将仅将重新分配的地址存储在函数的本地TargetsArray

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM