C函数用于释放2D,3D ...数组的内存

时间:2016-04-19 01:01:16

标签: c pointers memory-management dynamic

我有一个问题,在我的设置中我有这样的变量:

bool** array_2d_bool;
char** array_2d_char;

...

因此,为了释放内存,我有以下内容:

void free_bool(bool** mat, int m)
{
    int i;
    for (i = 0; i < m; i++)
    {
        free(mat[i]);
    }
    free(mat);
}

但是,我必须为我要解除分配的每种类型的2D或3D数组编写一个函数。有没有办法写这样的函数?:

void deallocate_2d(void**, int m)

这样我就可以使用一个函数来解除分配任何2D数组......

3 个答案:

答案 0 :(得分:2)

bool** array_2d_bool;
char** array_2d_char;

这些不是2D数组,不能用于指向2D数组。它们最多可用于指向指针数组的第一个元素。

您希望使用指针数组的唯一原因是您需要查找表,其中每个指向类型具有不同的长度,例如字符串查找表或链式哈希表。这不是这种情况,你只需要一个2D数组。

使用指向指针动态分配2D数组总是错误的,原因有多种:它不会创建实际的数组(所以你不能使用memcpy()和类似的在它上面,它涉及复杂的分配/释放,可能导致泄漏,它导致堆分割和较慢的分配,它提供较差的缓存性能等等。

而是分配2D数组:

malloc( sizeof(bool[x][y] );

然后用数组指针指向它。

bool (*array_2d_bool)[x][y] = malloc( sizeof(bool[x][y] );

为了便于使用,指向此数组数组中的第一个数组更方便,而不是指向整个2D数组。所以改成它:

bool (*array_2d_bool)[y] = malloc( sizeof(bool[x][y] );

现在您可以将其用作array_2d_bool[i][j]

当你完成后,释放它:

free(array_2d_bool);

答案 1 :(得分:0)

你没有nD阵列。指针不是数组。它们也有不同的语义。

使用真正的nD数组可以直接进行解除分配:

#define INNER 10
#define OUTER 20

int (*arr)[INNER] = malloc(sizeof(*arr) * OUTER);

...

free(arr);

除了声明之外,这对于更多维度来说是直截了当的。 free甚至是一样的。无需单独的释放功能。

答案 2 :(得分:0)

在计算科学中,malloc() 1D“数组”(即m n doubledouble *a=malloc(m*n*sizeof(double))矩阵对你来说非常标准。单个i),然后自己进行索引计算,即获取存储在jaa[i*n+j]的元素,使用malloc()。这有几个优点,包括它不需要执行多个/嵌套free()try { ClientCredential clientCredential = new ClientCredential("***********","**************"); UserIdentifier userIdentifier = new UserIdentifier(userObjectId, UserIdentifierType.UniqueId); DiscoveryClient discClient = new DiscoveryClient(SettingsHelper.DiscoveryServiceEndpointUri, async () => { var authResult = await authContext.AcquireTokenSilentAsync(SettingsHelper.DiscoveryServiceResourceId, clientCredential, userIdentifier); return authResult.AccessToken; }); var dcr = await discClient.DiscoverCapabilityAsync(capabilityName); return new OutlookServicesClient(dcr.ServiceEndpointUri, async () => { var authResult = await authContext.AcquireTokenSilentAsync(dcr.ServiceResourceId, clientCredential, userIdentifier); return authResult.AccessToken; }); } catch (AdalException exception) { //Handle token acquisition failure if (exception.ErrorCode == AdalError.FailedToAcquireTokenSilently) { authContext.TokenCache.Clear(); throw exception; } return null; } s,对程序员的认知开销几乎没有增加,特别是因为你可以抽象索引计算远离一点内联函数或一个宏,并且很容易扩展到更高的维度。

更详细的解释可以在this answer中找到。