通过C中的memcpy将Matrix复制到另一个

时间:2014-03-09 08:40:22

标签: c matrix memcpy void-pointers

我想编写一个函数,通过使用memcpy将两个矩阵复制到一个矩阵中。就像C = [A; B]在Matlab中。因为,我想对所有类型的数据使用这个函数,这意味着整数和浮点矩阵,我使用了void指针。

代码是:

void Repmatrix(void *M3, void *M1, int R1, int C1, void *M2, int R2, int C2, size_t t)
{
    if (RC == 'R')
    {
        int i;
        for (i = 0; i < R1*C1; i++)
        {
            memcpy(M3+i, M1+i, t);

        }
        for (j = 0; j < R1*C1; j++)
        {
            memcpy(M3+i+j, M1+j, t);

        }
    }
}

感谢任何帮助和建议。

为了澄清它,输入是:

M1 = [
1 2
3 4]
M2 = [
5 6
7 8]

输出应为:

M3 = [
1 2
3 4
5 6
7 8]

1 个答案:

答案 0 :(得分:1)

首先,有一些简单的索引错误,可能是因为你复制并粘贴了循环:第二个循环应该使用M2C2R2

然后,正如其他人所指出的那样,你无法对void *进行算术运算。无效指针只是匿名句柄。如果你想对它们做一些事情,你应该将它们转换为指向值类型的指针。 (GCC似乎允许对void *进行算术运算并将其视为char *;它只会在-pedantic模式下发出警告。)

因为您不知道函数中的值类型,只知道它的大小,所以将它们转换为char *,因为sizeof(char) == 1。然后你可以在指针算术中使用你的大小t,如下所示:

void Repmatrix(void *M3, 
    void *M1, int R1, int C1, 
    void *M2, int R2, int C2, size_t t)
{
    char *MM1 = M1;
    char *MM2 = M2;
    char *MM3 = M3;
    int i, j;

    for (i = 0; i < R1*C1; i++) {
        memcpy(MM3 + i * t, MM1 + i * t, t);
    }

    for (j = 0; j < R2*C2; j++) {
        memcpy(MM3 + (i + j) * t, MM2 + j * t, t);
    }
}

您实际上并不需要循环,因为如果以矩阵形式存储矩阵,则上半部分和下半部分的内存是连续的:

void Repmatrix(void *M3,
    void *M1, int R1, int C1,
    void *M2, int R2, int C2, size_t t)
{
    char *top = M3;
    char *btm = top + R1 * C1 * t;

    memcpy(top, M1, R1 * C1 * t);
    memcpy(btm, M2, R2 * C2 * t);
}

更加类型安全的变体是坚持double作为矩阵值并使用double *指针:

void Repmatrix(double *M3,
    double *M1, int R1, int C1,
    double *M2, int R2, int C2)
{
    memcpy(M3, M1, R1 * C1 * sizeof(*M3));
    memcpy(M3 + R1 * C1, M2, R2 * C2 * sizeof(*M3));
}

你仍然必须使用sizeof,因为memcpy适用于void指针,但你会发现任何将错误的指针类型传递给Repmatrix的事件。