我有一个问题,在我的设置中我有这样的变量:
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数组......
答案 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
double
个double *a=malloc(m*n*sizeof(double))
矩阵对你来说非常标准。单个i
),然后自己进行索引计算,即获取存储在j
中a
,a[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中找到。