簡體   English   中英

動態分配的矩陣在打印時出現段錯誤

[英]dynamically allocated matrix gives seg fault when printed

該代碼通過一系列函數調用分配矩陣,但是當我打印它時,它返回一個分段錯誤錯誤。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void mat_init(int** matx);
void pp_init(int** matx);
void p_init(int** matx);
void mat_fill(int** matx);
void mat_print(int** matx);

int main(void)
{
    srand((unsigned)time(NULL));
    int** matrix;
    mat_init(matrix);
    mat_print(matrix);
    return 0;
}

void mat_init(int** matx)
{
    pp_init(matx);
}

void pp_init(int** matx)
{

    matx=malloc(4*sizeof(int*));
    p_init(matx);
}

void p_init(int** matx)
{
    for(int i=0;i<4;i++)
    {
        *(matx+i)=malloc(4*sizeof(int));
    }
    mat_fill(matx);
}

void mat_fill(int** matx)
{
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            *(*(matx+i)+j)=rand()%5;
        }
    }
    //mat_print(matx);
}

void mat_print(int** matx)
{
    printf("The matrix is:\n");
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            printf("%1i|",*(*(matx+i)+j));
        }
        puts("");
    }
    puts("");
}

請注意,只有當我在主菜單中使用mat_print()來打印矩陣時,才會發生這種情況;如果我在mat_fill()函數中使用該矩陣,則它會正常工作,表明已正確初始化。 有什么問題?

您需要這樣做:

int** mat_init(int** matx);
int** pp_init(int** matx);

int main(void)
{
    matrix=mat_init(matrix);
}

int** mat_init(int** matx)
{
    return pp_init(matx);
}

int** pp_init(int** matx)
{
    matx=malloc(4*sizeof(int*));
    p_init(matx);
    return matx;
}

我省略了一些我沒有更改的行。 另一個選擇是:

void mat_init(int*** matx);
void pp_init(int*** matx);

int main(void)
{
    mat_init(&matrix);
}

void mat_init(int*** matx)
{
    pp_init(matx);
}

void pp_init(int*** matx)
{
    *matx=malloc(4*sizeof(int*));
    p_init(*matx);
}

另一件事:您在很多地方都使用值4 太危險了 改用常量。

#define MAT_SIZE 4

void mat_fill(int** matx) {
    for(int i=0;i<MAT_SIZE;i++) {
        for(int j=0;j<MAT_SIZE;j++)

本質上,您正在執行的操作是:

void foo(int a);
{
  a = 6;
}

int main()
{
  int a = 3;
  foo(a);
  printf("a = %d\n", a);  // expecting this to print 6

  return 0;
}

C語言中的所有內容都是按值傳遞的,這意味着每當將參數傳遞給函數時,都會在該函數中創建其本地副本,並且其作用域僅存在於該函數中。 指針也不例外。 如果我有以下代碼:

void foo (int* ap2)
{
  // there are now 2 pointers in memory that point to the same thing (main's a), namely
  // ap2 on this stack frame and ap1 in the previous stack frame.
  *ap2 = 6;
  // ap2 is local to this function, but it _points_ to the same thing as
  // ap1, so when we dereference it, changes to _what it points to_ are seen
  // outside of this function. But once we return from this function, ap2
  // ceases to exist
}

int main()
{
  int a = 3;
  int* ap1 = &a;
  foo(ap1);
  printf("a = %d\n", a);  // now this prints 6

  return 0;
}

如果要在函數中操作mainmatx ,則需要傳遞一個指向它的指針並在該函數中取消引用它,以修改其指向的對象

void foo (int*** matxp)
{
  // matxp now points to matx in main
  // dereference it here
  *matxp = malloc(4 * sizeof(int*));
}
int main()
{
  int** matx;
  foo(&matx);  // pass the address of matx here, which is an int*** type

  ....

  // don't forget to clean up everything
  return 0;
}

但是正如我在評論中所說,我很少/從未見過3星指針。 相反,您可以只返回值

int** foo()
{
  matxp = malloc(4 * sizeof(int*));
  return matxp;  // this will return NULL if malloc failed
}

int main()
{
  int** matx = foo();

  ....
  // do work, cleanup
  return 0;
}

暫無
暫無

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

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