簡體   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