_"I am trying to modify a 2D array from a void function."_
这里有一些提示和修复,它们允许您将内存更新为一个由两个指向 int 的指针组成的数组。 (请参阅代码中的注释)
void try_by_reference(int **arr){
//always use a temporary variable to call realloc, otherwise if failed attempt - memory leak will occur
int *tmp = realloc(*arr, 2 * sizeof(*arr));//this effectively reduces memory from original 10, to 2 instances of int
if(!tmp)//always check return of realloc, if it fails free original memory and return
{
free(*arr);
//set pointer to NULL here to provide way to test before
//freeing later in process. (See 'Reference' below)
*arr = NULL;//to prevent problems in subsequent free calls
return;
}
else *arr = tmp;
}
int main(int argc, char **argv){
// declare dynamic 2d-array and allocate memory
int *arr[2] = {NULL, NULL};//this is an array of 2 pointers to int - each
//need to be allocated
//it will result in an array shaped as array[2][10]
//after following calls to malloc.
arr[0] = malloc(10*sizeof(arr[0]));//original provides memory for 10 instances of int
if(arr[0])
{
arr[1] = malloc(10*sizeof(arr[1]));
if(arr[1])
{
// fill array
//for (int i=0; i<10; i++){
for (int i=0; i<10; i++){
//arr[i][0] = i;
//arr[i][1] = i+10;
arr[0][i] = i;//switch indices
arr[1][i] = i+10;//switch indices
}
}
}
// declare and fill a simpler dynamic array
int *tarr = malloc(sizeof(int) * 10);
for (int i=0; i<10; i++)
tarr[i] = i*2;
try_by_reference(&tarr);
//try_by_reference(&arr); <-- this gets warning
//pass address of each pointer to memory, one at a time
try_by_reference(&(arr[0]));
try_by_reference(&(arr[1]));
//To prevent UB from calling free on an already freed pointer
//test before calling free.
if(arr[0]) free(arr[0]);//need to free each of two pointers to memory
if(arr[1] free(arr[1]);//...
if(tarr) free(tarr);
return 0;
}
参考关于why set pointer to NULL after freeing。如果对realloc() 的调用失败,从而导致释放原始指针,则设置指针== NULL 提供了一种方法来测试在稍后调用free(),从而避免调用的可能性undefined behavior (UB)。
有几种方法可以在 C 中创建不同形状的 nD 数组内存,其中一些方法比int *arr[2] 更容易更新内存。但我坚持使用这个表格来具体说明一种更新它的方法。虽然访问元素需要更严格,但对于通过指针实现的 int[2][10],我更喜欢创建一个int *arr = malloc(2*10*sizeof(*arr));。观察以下示例以进行易用性比较。 (使用 2D like,但尺寸不同):
int arr1[3][6] = {{1,2,3,4,5,6},{7,8,9,10,11,12},{13,14,15,16,17,18}};
//same memory as
int arr2[18] = {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}};
knowing that *(arr1 + 2*6 + 5) == arr2[2][5] = 18;
*(arr1 + 0*6 + 4) == arr2[0][4] = 5;
*(arr1 + 1*6 + 0) == arr2[1][0] = 7;
// | | |_2nd index range 0 - 5
// | |_ constant -> sizeof(arr1[0]/arr1[0][0])
// |1st index range is from 0 - 2
The same is true for dynamic memory. int **arr1 and *arr2
int **arr1 //requires 7 calls to malloc/free
int *arr2 //requires 1 call to malloc/free