memcpy段错误与更大的数组

时间:2015-09-08 01:45:57

标签: c multidimensional-array memcpy

我有一个使用memcpy在C中交换2d数组的函数。我知道你可以交换指针,但我想在复制数组和交换指针之间进行比较。

这是我的代码,2d数组是n x n。

void swap_arrays(int n, float old[][n], float new_arr[][n]) {
    float temp[n][n];
    int arr_size = sizeof(float) * n * n;
    memcpy(temp, old, arr_size);
    memcpy(old, new_arr, arr_size);
    memcpy(new_arr, temp, arr_size);
}

它适用于5 x 5数组,但是当数组较大时(我需要的实际大小为4000+,它会在2000+处开始分段错误),在第一个memcpy时会出现段错误。任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:6)

它有4000个段错误,但它不是memcpy()的错。这是因为大小超过了程序的堆栈大小。

尝试动态分配数组,它应该可以正常工作,就像这样

float *temp;
temp = malloc(sizeof(float) * n * n);
if (temp != NULL)
{
    /* memcpys here */
}

请注意,与数组不同,这不能通过两个索引表示法访问,以实现您需要的东西,如

float **temp;
temp = malloc(sizeof(float *) * n);
for (size_t i = 0 ; i < n ; ++i)
    temp[i] = malloc(sizeof(float) * n); /* please check for `NULL' */

在这两种情况下,您都需要free(),而在第二种情况下,您的memcpy()将无法正常工作。因为temp中的每个元素都是指针而不是float,所以首先需要访问指针,然后使用memcpy()复制数据。

答案 1 :(得分:3)

假设您的问题是temp过大导致的堆栈溢出,您可以动态分配空间。由于您只是在进行memcpying,因此不需要使用类型指针:

void swap_arrays(int n, float old[n][n], float new[n][n])
{
    size_t sz = sizeof(float[n][n]);
    void *buf = malloc(sz);
    if ( !buf ) exit(EXIT_FAILURE);

    memcpy(buf, old, sz);
    memcpy(old, new, sz);
    memcpy(new, buf, sz);

    free(buf);
}

当然,如果您在调用代码中编写float a[n][n];,则可能还会出现堆栈溢出问题。您也可以通过使用malloc解决这个问题,例如:

float (*a)[n] = malloc(n * sizeof *a);
float (*b)[n] = malloc(n * sizeof *b);

如果您使用后一种方法,那么您可以通过交换指针来“交换”,而无需复制所有数据:void *tmp = a; a = b; b = tmp;

答案 2 :(得分:0)

上面的答案都很好。正如@iharod指出你的程序超过了堆栈大小。如果您愿意,可以通过设置用户限制来增加堆栈大小。

如果您在Linux主机上运行:

alan@~$ulimit -all
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62978
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 62978
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

正如您所见,默认情况下堆栈大小为8192k

您可以使用ulimit命令设置堆栈大小,如:

alan@~$ulimit -s <stack_size_you_want>.

这仅用于说明目的,而不是推荐的解决方案。