MALLOC二维数组的功能

时间:2017-05-29 23:32:05

标签: c malloc

我正在练习使用malloc功能。我已经声明了两个复杂的矩阵:HresultH的所有元素都是1.1 + 0i,result的所有元素都是0 + 2.2i作为原始值。我已将H复制到result,然后将其打印出来。结果显示一些元素只是0 + 0i,显然不是这种情况。你能帮我弄清楚代码中出了什么问题吗?

/*
 * This C code is for simulation for printing complex channel matrix by using struct 
 *
 * let matrix H be 8 by 4
 * 2017.05.24
 *
 */

#include "math.h"
#include "complex.h"
#include <stdio.h>
#include <stdlib.h>

struct str_dcomplex
{
    double re;
    double im;
};

typedef struct str_dcomplex dcomplex;

int main() {

    void print_matrix(char* desc, int m, int n, dcomplex a[m][n]) {
        int i, j;
        printf("\n%s\n",desc);
        for(i = 0; i < m; i++) {
            for(j = 0; j < n; j++) {
                printf("(%5.1f,%5.1f)",a[i][j].re, a[i][j].im);
            }
        printf("\n");
        }
    }

    void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c]) {
        int i, j;
        for(i = 0; i < r; i++) {
            for(j = 0; j < c; j++) {
                dest[i][j].re = source[i][j].re;
                dest[i][j].im = source[i][j].im;
            }
        }
    }

    int p,q;
    int i,j;

    // memory allocation for H
    dcomplex **H;
    H = (dcomplex**)malloc(sizeof(dcomplex*)*8);
    for(p = 0; p < 8; p++) {
        H[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
    }

//  dcomplex(*H)[4] = dcomplex(*)[4]malloc(sizeof(dcomplex)*8*4);

    for(p = 0; p < 8; p++) {
        for(q = 0; q < 4; q++) {
            H[p][q].re = 1.1;
            H[p][q].im = 0.0;
        }
    }

    dcomplex** result;
    result = (dcomplex**)malloc(sizeof(dcomplex*)*8);
    for(p = 0; p < 8; p++) {
        result[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
    }

    for(p = 0; p < 8; p++) {
        for(q = 0; q < 4; q++) {
            result[p][q].re = 0.0;
            result[p][q].im = 2.2;
        }
    }


    // declare and assign variables
    //dcomplex H[8][4] = {{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}}};
    //dcomplex result[8][4] = {{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}}};

    // print H and result
    print_matrix("original H is: \n",8,4,H);
    print_matrix("original result is: \n",8,4,result);

    // copy H to result
    matrix_copy(8,4,H,result);

    // print H and result
    print_matrix("new H is: \n",8,4,H);
    print_matrix("new result is: \n",8,4,result);

    int count = 0;
    for(i = 0; i < 8; i++) {
        for(j = 0; j < 4; j++){
            if((H[i][j].re == result[i][j].re) && (H[i][j].im == result[i][j].im))
                count++;
        }
    }
    printf("\n%d\n\n",count);

    //printf("\nmatrix copy completed...\n\n");
    //printf("\nSize of dcomplex is: %d\n\n",sizeof(dcomplex));

    // free the memory
    for(i = 0; i < 8; i++) {
        free(H[i]);
    }
    free(H);

    for(i = 0; i < 8; i++) {
        free(result[i]);
    }
    free(result);

    return 0;
}

执行结果的屏幕截图: execution result screenshot

更新:我将print_matrixmatrix_copydcomplex a[m][n]的参数更改为dcomplex** a[m][n]dcomplex source[r][c]更改为{{1 }}和dcomplex** source[r][c] ...和desta[i][j].re等等。它仍然不起作用......无法弄清楚错误。

3 个答案:

答案 0 :(得分:1)

你正在使用malloc。

dcomplex **H;
H = (dcomplex**)malloc(sizeof(dcomplex*)*8);
for(p = 0; p < 8; p++) {
    H[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
}

我认为这些是有问题的行?您将不得不调试其余代码来解决问题。

答案 1 :(得分:1)

您没有使用<math.h><complex.h>中的任何内容 - 您使用自己的dcomplex类型。那些标题也可能不存在。

嵌套函数符号是令人厌恶的 - GCC允许它,但它不应该,并且你不应该使用符号。

当函数被取消时(我拒绝找出它们嵌套时会发生什么),编译器会痛苦而公正地抱怨:

cx19.c: In function ‘main’:
cx19.c:76:42: error: passing argument 4 of ‘print_matrix’ from incompatible pointer type [-Werror=incompatible-pointer-types]
     print_matrix("original H is: \n",8,4,H);
                                          ^
cx19.c:15:6: note: expected ‘dcomplex (*)[(sizetype)(n)]’ but argument is of type ‘dcomplex ** {aka struct str_dcomplex **}’
 void print_matrix(char* desc, int m, int n, dcomplex a[m][n]) {
      ^~~~~~~~~~~~
cx19.c:77:47: error: passing argument 4 of ‘print_matrix’ from incompatible pointer type [-Werror=incompatible-pointer-types]
     print_matrix("original result is: \n",8,4,result);
                                               ^~~~~~

您传递dcomplex **并假装它是dcomplex[m][n]类型。我很遗憾地通知您编译器是正确的并且您的代码是错误的。

如果要传递可变长度的2D数组,则必须分配可变长度的2D数组。如果要将指针传递给指针,则必须修改函数。

使用动态分配的指针数组

更改功能很容易;只需更改相关参数的类型即可。请注意,除了函数签名的更改之外,函数没有其他必要的更改。

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

struct str_dcomplex
{
    double re;
    double im;
};

typedef struct str_dcomplex dcomplex;

static
void print_matrix(char* desc, int m, int n, dcomplex **a) {
    int i, j;
    printf("\n%s\n",desc);
    for(i = 0; i < m; i++) {
        for(j = 0; j < n; j++) {
            printf("(%5.1f,%5.1f)",a[i][j].re, a[i][j].im);
        }
        putchar('\n');
    }
}

static
void matrix_copy(int r, int c, dcomplex **source, dcomplex **dest) {
    int i, j;
    for(i = 0; i < r; i++) {
        for(j = 0; j < c; j++) {
            dest[i][j].re = source[i][j].re;
            dest[i][j].im = source[i][j].im;
        }
    }
}

int main(void) {
    int p,q;
    int i,j;

    // memory allocation for H
    dcomplex **H;
    H = (dcomplex**)malloc(sizeof(dcomplex*)*8);
    for(p = 0; p < 8; p++) {
        H[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
    }

    for(p = 0; p < 8; p++) {
        for(q = 0; q < 4; q++) {
            H[p][q].re = 1.1;
            H[p][q].im = 0.0;
        }
    }

    dcomplex** result;
    result = (dcomplex**)malloc(sizeof(dcomplex*)*8);
    for(p = 0; p < 8; p++) {
        result[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
    }

    for(p = 0; p < 8; p++) {
        for(q = 0; q < 4; q++) {
            result[p][q].re = 0.0;
            result[p][q].im = 2.2;
        }
    }

    // print H and result
    print_matrix("original H is: \n",8,4,H);
    print_matrix("original result is: \n",8,4,result);

    // copy H to result
    matrix_copy(8,4,H,result);

    // print H and result
    print_matrix("new H is: \n",8,4,H);
    print_matrix("new result is: \n",8,4,result);

    int count = 0;
    for(i = 0; i < 8; i++) {
        for(j = 0; j < 4; j++){
            if((H[i][j].re == result[i][j].re) && (H[i][j].im == result[i][j].im))
                count++;
        }
    }
    printf("\n%d\n\n",count);

    // free the memory
    for(i = 0; i < 8; i++) {
        free(H[i]);
    }
    free(H);

    for(i = 0; i < 8; i++) {
        free(result[i]);
    }
    free(result);

    return 0;
}

该输出是:

original H is: 

(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)

original result is: 

(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)
(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)
(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)
(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)
(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)
(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)
(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)
(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)(  0.0,  2.2)

new H is: 

(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)

new result is: 

(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)
(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)(  1.1,  0.0)

32

使用动态分配的可变长度数组

动态分配可变长度数组并将它们传递给函数也是完全可行的。这导致代码如下:

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

struct str_dcomplex
{
    double re;
    double im;
};

typedef struct str_dcomplex dcomplex;

static void print_matrix(char *desc, int m, int n, dcomplex a[m][n])
{
    int i, j;
    printf("\n%s\n", desc);
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
            printf("(%5.1f,%5.1f)", a[i][j].re, a[i][j].im);
        putchar('\n');
    }
}

static void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c])
{
    int i, j;
    for (i = 0; i < r; i++)
    {
        for (j = 0; j < c; j++)
            dest[i][j] = source[i][j];
    }
}

int main(void)
{
    int p, q;
    int i, j;

    // memory allocation for H
    dcomplex(*H)[4] = malloc(sizeof(H[0]) * 8);
    assert(H != 0);  // Sloppy!

    for (p = 0; p < 8; p++)
    {
        for (q = 0; q < 4; q++)
            H[p][q] = (dcomplex){ .re = 1.1, .im = 0.0 };
    }

    dcomplex (*result)[4] = malloc(sizeof(result[0]) * 8);
    assert(result != 0);  // Sloppy!

    for (p = 0; p < 8; p++)
    {
        for (q = 0; q < 4; q++)
            result[p][q] = (dcomplex){ .re = 0.0, .im = 2.2 };
    }

    // print H and result
    print_matrix("original H is:", 8, 4, H);
    print_matrix("original result is:", 8, 4, result);

    // copy H to result
    matrix_copy(8, 4, H, result);

    // print H and result
    print_matrix("new H is:", 8, 4, H);
    print_matrix("new result is:", 8, 4, result);

    int count = 0;
    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if ((H[i][j].re == result[i][j].re) && (H[i][j].im == result[i][j].im))
                count++;
        }
    }
    printf("\n%d\n\n", count);

    // free the memory
    free(H);
    free(result);

    return 0;
}

代码还使用了一些带有指定初始值设定项的复合文字,并且松散错误检查内存分配。使用assert()进行错误检查在生产代码中是不明智的;这不是生产代码,它就足够了。

输出非常相似 - 矩阵描述和矩阵数据之间没有空行。

使用常规可变长度数组

#include <stdio.h>

struct str_dcomplex
{
    double re;
    double im;
};

typedef struct str_dcomplex dcomplex;

static void print_matrix(char *desc, int m, int n, dcomplex a[m][n])
{
    printf("\n%s\n", desc);
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
            printf("(%5.1f,%5.1f)", a[i][j].re, a[i][j].im);
        putchar('\n');
    }
}

static void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c])
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            dest[i][j] = source[i][j];
    }
}

static void matrix_init(int r, int c, dcomplex target[r][c], dcomplex value)
{
    for (int p = 0; p < r; p++)
    {
        for (int q = 0; q < c; q++)
            target[p][q] = value;
    }
}

int main(void)
{
    int r = 8;
    int c = 4;

    dcomplex H[r][c];
    matrix_init(r, c, H, (dcomplex){ .re = 1.1, .im = 0.0 });

    dcomplex result[r][c];
    matrix_init(r, c, result, (dcomplex){ .re = 0.0, .im = 2.2 });

    // print H and result
    print_matrix("original H is:", r, c, H);
    print_matrix("original result is:", r, c, result);

    // copy H to result
    matrix_copy(r, c, H, result);

    // print H and result
    print_matrix("new H is:", r, c, H);
    print_matrix("new result is:", r, c, result);

    int count = 0;
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
        {
            if ((H[i][j].re == result[i][j].re) && (H[i][j].im == result[i][j].im))
                count++;
        }
    }
    printf("\n%d\n\n", count);

    return 0;
}

使用可变长度数组的更改很简单,这意味着我们不再需要使用<stdlib.h>。我创建了matrix_init()函数来初始化数组 - 它减少了main()函数中的重复。如果使用在运行时确定的数组大小,则必须对数组大小进行完整性检查;堆栈上有多少可用空间是有限制的。但是,这些数组的大小(8 * 4 * 2 * sizeof(double),通常为512字节)不会给任何现代桌面计算机带来压力。

使用经典固定大小数组的改变是微不足道的。设置rc值的更改同样基本上是微不足道的。

答案 2 :(得分:-2)

我不确定这是不是问题,而是将dcomplex dest传递给了 void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c])仅传递该值。您应该将matrix_copy(8,4,H,result)更改为matrix_copy(8,4,H, &result)void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c])void matrix_copy(int r, int c, dcomplex **source, dcomplex ***dest)