快速复制数组的方法

时间:2015-11-11 21:20:07

标签: c arrays pointers optimization multidimensional-array

所以在我正在做的每次迭代结束时,我想让我的数组等于我的新数组(我称之为array_new)。我希望数组的每个元素都采用与array_new相同的值,但我有兴趣尽可能快地获取代码,因此在当前代码执行的情况下逐个元素复制所有内容不是一个选项:< / p>

for(i=0;i<N_a;i++) {
  for(j=0;j<N_b;j++) {
    array[i][j] = array_new[i][j];
  }
}

这需要相当长的时间,因为我的N_a和N_b的值非常大。有没有办法简单地改变每个指向的内容,以便我可以更快地开始下一次迭代?我尝试过像

这样的东西
 double *temp = *array;
 *array = *array_new;
 *array_new = temp;

为了尝试避免缓慢的逐个元素复制过程,但它似乎对我不起作用。实际上,我正在努力实现的是,数组的每个元素都指向array_new中的相应元素,但我无法弄清楚如何使指针执行此操作。

非常感谢任何帮助!

4 个答案:

答案 0 :(得分:7)

由于数组的内存大小是固定的,因此您只需将内存块从一个指针复制到另一个指针即可。它没有比这更快。

c/c++中,如果您使用的语言是memcpy,则可以使用c。每种语言都有相同的东西。

编辑:自从您确认使用memcpy(array_new,array,sizeof(VARIABLE_TYPE_of_ARRAY_ELEMENT)*N_a*N_b); 后,我可以获得更详细的信息:

^E+[^ED]*D+$

答案 1 :(得分:0)

您的指针交换代码有点偏离:您正在取消引用您不应该指向的指针。毕竟,该代码的重点是避免仅通过交换两个指针来复制数据。以下是正确的版本(取决于您使用的是真正的2D数组还是指向数组的指针数组):

//array is declared as
double (*array)[N_b];

double (*temp)[N_b] = array;
array = array_new;
array_new = temp;

//array is declared as
double** array;

double** temp = array;
array = array_new;
array_new = temp;

这就是您所需要的,它绝对是交换两个缓冲区内容的最快方式。比memcpy() ...

快得多

答案 2 :(得分:0)

两个回答这个问题,首先需要了解数组在内存中的表示方式。例如。看到这个问题:How are multi-dimensional arrays formatted in memory?

首先,我们需要知道您是否有静态数组。如果它是静态数组,则任务特别简单,因为数据在内存中连续布局。这意味着如果你有一个2x2静态数组,内容为{{9, 8}, {7, 6}},你的内存可能如下所示:

Address  0  1  2  3  4  5  6  7  8
Content  ?  ?  9  8  7  6  ?  ?  ?

在这种情况下,您的变量声明如下:

int[2][2] myArray;

实际上是指向地址“2”的指针,您可以轻松复制整个事物。用memcpy:

int [2][2] newArray;
memcpy(&newArray, &myArray, sizeof(int)*2*2);

请注意,此副本从“myArray”指向的位置(在我的示例中为2)与2 * 2 * sizeof(int)一样多的字节。所以int的大小是4倍。 (为简单起见,我的示例假设int的大小为一个字节,但当然在大多数系统上它是4个字节)。

如果你有一个动态数组,那么这是一个不同的故事。在这种情况下,您的数组的内存声明如下:

int** myArray;

可能看起来像这样:

Address  0  1  2  3  4  5  6  7  8
Content  9  8  0  6  ?  ?  7  6  ?

请注意,指针myArray仍然指向地址“2”。但是,在地址“2”处,您找不到第一个值,而是另一个指向“0”的指针。在这里,您可以找到第一个“行”的值,即9和8。 在数字“3”的地址“2”旁边,您可以找到指向第二个“行”的指针,该指针从第6位开始。如您所见,您仍然可以找到所有数据,但无法一次性复制它们。要复制整个数组,至少需要外行:

int SIZE_X = 2;
int SIZE_Y = 2;
int** newArray = malloc(sizeof(int*)*SIZE_X);
for(i = 0; i < SIZE_X; ++i) {
  newArray[i] = malloc(sizeof(int)*SIZE_Y);
  memcpy(newArray[i], myArray, SIZE_Y*sizeof(int));
}

这应该比使用两个循环更快,memcpy can use more efficient ways to copy than a copy loop

答案 3 :(得分:0)

如果您只想交换指针,不是物理复制数据,并且仍然能够使用索引访问数组,下面是一个如何完成它的示例:

#define N_a 2
#define N_b 3

typedef struct arr 
{ 
    int val[N_a][N_b]; 
} arr;

arr array     = {{{11,12,13},{14,15,16}}};
arr array_new = {{{21,22,23},{24,25,26}}};

int main()
{
    arr *p_array;
    arr *p_array_new;

    p_array     = &array;
    p_array_new = &array_new;
    printf("%d %d\n", p_array->val[1][2], p_array_new->val[1][2]);
    // output: 16 26

    p_array     = &array_new;
    p_array_new = &array;
    printf("%d %d\n", p_array->val[1][2], p_array_new->val[1][2]);
    // output: 26 16
}