首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >访问预定义数组时代码崩溃

访问预定义数组时代码崩溃
EN

Stack Overflow用户
提问于 2017-03-15 07:04:28
回答 2查看 74关注 0票数 2

我很难理解为什么我的代码在访问数组时崩溃。当将函数param转换为int[3][3]而不是int**时,我没有问题,但我不明白为什么,因为作为参数给出的int**是指向main中定义的本地内存的有效指针

代码语言:javascript
复制
typedef struct {const unsigned int m; const unsigned int n;} mat_size;

void print_mat(int** mat, mat_size s){  // <-- faulty version
    int i,j;
    for(i = 0; i < s.m; i++){
        for(j = 0; j < s.n; j++){
            printf("%d ", mat[i][j]);
        }
        printf("\n");
    } 
    printf("=============");
}


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

    int matrix[3][3] = {{1,4,2},{7,-1,15},{33,-10,-1}};
    mat_size s = {3,3};
    print_mat(matrix, s);  

    while(1);
    return 0;
}

void print_mat(int mat[3][3], mat_size s){  // <-- good version
    int i,j;
    for(i = 0; i < s.m; i++){
        for(j = 0; j < s.n; j++){
            printf("%d ", mat[i][j]);
        }
        printf("\n");
    } 
    printf("=============");
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-15 07:16:36

函数参数的类型与传递的矩阵不匹配,因为matrix[3][3]不是int**,而是(*int)[3]

在注释中,您还希望您的矩阵具有动态大小,这样您就可以使用VLA执行此操作:

代码语言:javascript
复制
#include <stdio.h>

typedef struct
{
    const unsigned int m;
    const unsigned int n;
} mat_size;

void print_mat(mat_size s, int (*mat)[s.n])
{
    unsigned int i, j;
    for (i = 0; i < s.m; i++)
    {
        for (j = 0; j < s.n; j++)
        {
            printf("%d ", mat[i][j]);
        }
        printf("\n");
    }
    printf("=============\n");
}

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

    int matrix[3][3] = { { 1, 4, 2 }, { 7, -1, 15 }, { 33, -10, -1 } };
    mat_size s = { 3, 3 };
    print_mat(s, matrix);

    return 0;
}
票数 3
EN

Stack Overflow用户

发布于 2017-03-15 07:38:03

被声明为函数参数的数组由编译器静默地调整到第一个对象。这就是为什么

代码语言:javascript
复制
void func (int a[5]);

等于

代码语言:javascript
复制
void func (int* a);

类似地,调用方声明并传递给这样一个函数的数组也会“衰变”为指向第一个元素的指针。

这背后的原理是,数组不应该通过值传递给函数,因为获取数组的硬拷贝会占用执行时间和内存。

对于多维数组,同样的规则也适用.给定一个函数void print_mat(int mat[3][3]),数组将被静默地调整为指向第一个元素的指针。int [3][3]数组中的第一个元素是类型为int[3]的数组。因此,指向这样一个元素的指针必须是数组指针,int (*)[3]

因此,void print_mat(int mat[3][3])等同于void print_mat(int (*mat)[3])。因此,您可以更改函数使用这样的数组指针,它将是等效的。

但是,我建议使用可变方法来代替:

代码语言:javascript
复制
void print_mat (size_t x, size_t y, int mat[x][y])

指针指向指针与多维数组无关,尽管它们可以用来模拟动态内存分配。然而,这样做往往是不好的和不正确的做法。有关这方面的更多信息,请参见正确分配多维数组

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42803110

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档