连续二维数组的重新分配
我正在使用 Shawn Chin 在此发布的方法生成连续的二维数组。[1][2]它运作得很好。
简要摘自他的文章:
char** allocate2Dchar(int count_x, int count_y) {
int i;
# allocate space for actual data
char *data = malloc(sizeof(char) * count_x * count_y);
# create array or pointers to first elem in each 2D row
char **ptr_array = malloc(sizeof(char*) * count_x);
for (i = 0; i < count_x; i++) {
ptr_array[i] = data + (i*count_y);
}
return ptr_array;
}
以及以下自由函数:
void free2Dchar(char** ptr_array) {
if (!ptr_array) return;
if (ptr_array[0]) free(ptr_array[0]);
free(ptr_array);
}
对我来说,如何在任一维度创建等效的重新分配函数并不明显,尽管我只对在保持连续性的同时重新分配行数感兴趣。增加列的数量很容易理解,但可能相当困难。除了说“这很难!”之外,我没有发现任何关于这个问题的直接讨论。[2]
当然,这可以通过可怕的蛮力方法来实现,将数据复制到新的一维数组(上面的数据)进行存储,重新分配一维数组,然后释放并重新生成指向行元素的指针(ptr_array)新尺寸。然而,这对于行修改来说相当慢,因为需要至少加倍内存需求才能复制出数据,这对于更改列数来说确实非常糟糕。
这是用于更改行数的所述方法的示例(它无法正常更改列数,因为指针的偏移量对于数据来说是错误的)。我还没有完全测试过这个,但你明白了...
double **
reallocate_double_array (double **ptr_array, int count_row_old, int count_row_new, int count_col)
{
int i;
int old_size = count_row_old * count_col;
int new_size = count_row_new * count_col;
double *data = malloc (old_size * sizeof (double));
memcpy (&data[0], &ptr_array[0][0], old_size * sizeof (double));
data = realloc (data, new_size * sizeof (double));
free (ptr_array[0]);
free (ptr_array);
ptr_array = malloc (count_row_new, sizeof (double *));
for (i = 0; i < count_row_new; i++)
ptr_array[i] = data + (i * count_col);
return ptr_array;
}
另外,这个方法需要你知道以前的尺寸,这很令人讨厌!
任何想法都非常感激。
[2] http://www.eng.cam.ac.uk/help/tpl/languages/C/teaching_C/node52.html
I am generating contiguous 2d arrays using the method posted on here by Shawn Chin.[1][2] It works very well.
Briefly from his post:
char** allocate2Dchar(int count_x, int count_y) {
int i;
# allocate space for actual data
char *data = malloc(sizeof(char) * count_x * count_y);
# create array or pointers to first elem in each 2D row
char **ptr_array = malloc(sizeof(char*) * count_x);
for (i = 0; i < count_x; i++) {
ptr_array[i] = data + (i*count_y);
}
return ptr_array;
}
And the following free function:
void free2Dchar(char** ptr_array) {
if (!ptr_array) return;
if (ptr_array[0]) free(ptr_array[0]);
free(ptr_array);
}
It is not obvious to me how to create an equivalent reallocate function in either dimension, though I am only interested in realloc'ing the number of rows while maintaining continuity. Growing the number of columns would be interesting to understand but probably quite difficult. I haven't found any direct discussion of this issue anywhere other than to say, "it's hard!".[2]
Of course this is doable by a horrible brute force method, copying the data to a new 1D array (data, above) for storage, realloc'ing the 1D array, then freeing and regenerating the pointers (ptr_array) to the row elements for the new size. This, however, is pretty slow for row modifications, since it is necessary to at least double the memory requirement to copy out the data, and this is truly horribly bad for changing the number of columns.
This is an example of said method for changing the number of rows (it wouldn't work properly for changing the number of columns because the offsets for the pointers would be wrong for the data). I haven't fully tested this, but you get the idea ...
double **
reallocate_double_array (double **ptr_array, int count_row_old, int count_row_new, int count_col)
{
int i;
int old_size = count_row_old * count_col;
int new_size = count_row_new * count_col;
double *data = malloc (old_size * sizeof (double));
memcpy (&data[0], &ptr_array[0][0], old_size * sizeof (double));
data = realloc (data, new_size * sizeof (double));
free (ptr_array[0]);
free (ptr_array);
ptr_array = malloc (count_row_new, sizeof (double *));
for (i = 0; i < count_row_new; i++)
ptr_array[i] = data + (i * count_col);
return ptr_array;
}
Plus, this method requires you know the previous size, which is obnoxious!
Any thoughts greatly appreciated.
[1] How can I allocate a 2D array using double pointers?
[2] http://www.eng.cam.ac.uk/help/tpl/languages/C/teaching_C/node52.html
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
第一个 malloc 和 memcpy 是不必要的,因为您可以轻松访问
ptr_array[0]
处的原始数据数组。您不需要知道旧的大小,因为 realloc 应该回忆起它在该地址分配的大小并移动正确的数据量。像这样的东西应该有效。
The first malloc and the memcpy are unnecessary, because you have easy access to the original data array at
ptr_array[0]
. You don't need to know the old size, because realloc should recall how much it allocated at the address and move the correct ammount of data.Something like this should work.