簡體   English   中英

C中的MemoryManagement,在函數中傳遞指針,分段錯誤

[英]Memorymanagement in C, passing pointers in functions, segmentation fault

我有三個文件:

something.h

typedef struct {
    int size_t;
    char *c;
} p;

p ** createMatrix(int r, int c);

void printMatrix(p **matrix, const int r, const int c);

something.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "something.h"

p **
createMatrix(int r, int c)
{
    int rowsize=r*2+1;
    int colsize=c*2+1;

    /* memory alloc of rows */
    p **matrix=malloc(rowsize*sizeof(p *));
    int k;
    for(k=0; k<rowsize; k++)
    {
        /* memory alloc of columns */
        matrix[k]=malloc(colsize*sizeof(p));
    } 
    int i, j;
    for(i=0; i<rowsize; i++)
    {
        for(j=0; j<colsize; j++)
        {
            /* columns is between letters */
            if(j%2!=0)
            {   
                matrix[i][j].size_t=7;
                matrix[i][j].c=malloc(8*sizeof(char));
                strcpy(matrix[i][j].c,"       ");
            }
            else if(i%2==0 && j%2==0)
            {
                matrix[i][j].size_t=1;
                matrix[i][j].c=malloc(sizeof(char));
                *(matrix[i][j].c)='a';
            }
            else
            {
                matrix[i][j].size_t=1;
                matrix[i][j].c=malloc(sizeof(char));
                *(matrix[i][j].c)=' ';
            }
        }
    }       
    return matrix;
}

void
printMatrix(p **matrix, const int r, const int c)
{
    int rowsize=r*2+1;
    int colsize=c*2+1;
    printf("\n");
    int i, j;
    for(i=0; i<rowsize; i++)
    {
        printf("\t");
        for(j=0; j<colsize; j++)
        {
            if(matrix[i][j].size_t==1)
                printf("%c", *matrix[i][j].c);
            else
                printf("%s", matrix[i][j].c);

        }
        printf("\n");
    }
    printf("\n");
 }

main.c中

#include <stdlib.h>
#include <stdio.h>
#include "something.h"    

void
printMenufunction(p **matrix, int rows, int cols)
{
    int rowsize=rows*2+1;
    int colsize=cols*2+1;
    /* memory alloc of rows */
    matrix=malloc(rowsize*sizeof(p *));
    int i;
    for(i=0; i<rowsize; i++)
    /* memory alloc of columns */
        matrix[i]=malloc(colsize*sizeof(p));
    matrix=createMatrix(rows, cols);
}

int
main(void)
{
    int rows, cols;
    p **matrix;
    char stringtemp[3];
    printf("ask for row and col in form (5x5):\n");
    scanf("%s", stringtemp);
    sscanf(stringtemp, "%dx%d", &rows, &cols);
    printMenufunction(matrix, rows, cols);
    printMatrix(matrix, rows, cols);
    return 0;
}

這個代碼示例是我的prog的簡化版本,它給我一個分段錯誤。 我已經用gdb調試了它,所以我知道它在這些行之間的某個地方就是故障所在。 我要感謝一些幫助,謝謝。

更新:我無法調試此版本。 我的舊編程有很多代碼告訴我這是在這個區域,但至少我無法弄清楚在哪里? 那就是為什么我不能發布究竟是哪一行會導致分段錯誤。 如果我知道我認為我可以自己處理這個問題。 我希望有人能比我更清楚地看到它......

由於C是一個按值傳遞的語言,對函數參數的任何賦值都只修改參數的本地副本,因此當printMenufunction返回時, matrix仍未初始化。

您需要通過引用將指針傳遞給矩陣:

printMenufunction(&matrix, rows, cols);
printMatrix(&matrix, rows, cols);

並在函數內部取消引用。 例如:

//                       v Pointer to the double-pointer
void printMenufunction(p ***matrix, int rows, int cols)
{
    int rowsize=rows*2+1;
    int colsize=cols*2+1;
    /* memory alloc of rows */
//  v Dereferencing the pointer
    *matrix=malloc(rowsize*sizeof(p *));
   // ...
}

首先,對你來說,告訴我們gdb指出條線是錯誤的,而不僅僅是說“這是在這些線路中的某個地方”,這對我們有很大的幫助。 gdb應該能夠准確地告訴你哪一行觸發了錯誤。

話雖如此,這里有一個候選人:

char *stringtemp;
printf("ask for row and col in form (5x5):\n");
scanf("%s", stringtemp);

stringtemp尚未被分配到指向任何有意義的地方; 你所擁有的只是一個指針,其初始值是不確定的 這是一個潛在的段錯誤。 stringtemp分配緩沖區指向,或者只是將其分配為char數組:

char stringtemp[SOME_SIZE]; // where SOME_SIZE is as big as you need.

為什么要在printMenuFunction分配矩陣? 你為什么不使用你的createMatrix函數?!

編輯

我討厭變老; 余完全錯過了createMatrix正在從稱為printMenuFunction (這意味着malloc在呼叫printMenuFunction是冗余的並且需要被消除)。

重寫printMenuFunction ,如下所示:

void printMenuFunction(p ***matrix, int rows, int cols)
{
  *matrix = createMatrix(rows, cols);
}

請注意,在該函數中,如果需要訪問matrix元素,則需要應用下標之前取消引用它,例如

(*matrix)[i][j].size = ...;

重寫您的main內容如下:

int
main(void)
{
    int rows, cols;
    p **matrix;
    char stringtemp[3]; // 3 is not big enough to hold a string like "5x5";
                        // that requires an array size of *at least* 4.  
                        // "10x10" would require 6 characters.  You need
                        // an extra character for the 0 terminator.

    printf("ask for row and col in form (5x5):\n");
    scanf("%s", stringtemp);
    sscanf(stringtemp, "%dx%d", &rows, &cols);
    printMenufunction(&matrix, rows, cols); // note the & in front of matrix
    printMatrix(matrix, rows, cols);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM