我想像这样创建一个二维数组:
void **mdeclaraMatrice(int nrLini,int nrColoane, int sizeOfElement)
{
int i;
void **m = malloc(nrLini * 4);
if(m==NULL)
return NULL;
for(i=0; i<nrLini; i++)
{
*(m + (i*4)) = malloc(nrColoane * sizeOfElement);
if(*(m + (i*4)) == NULL)
return NULL;
}
return m;
}
我想这样用:
int **m = (int **)mdeclaraMatrice(n,m,sizeof(int));
但它不起作用。我做错了什么?
答案 0 :(得分:5)
您应该使用m[i]
而不是*(m+i*4)
并让编译器执行算术。
此外,如果发生故障,您应该释放已经分配的内存。
请改为尝试:
void **mdeclaraMatrice(int nrLini, int nrColoane, int sizeOfElement)
{
int i;
void **m = malloc(nrLini * sizeof(void*));
if (m == NULL)
return NULL;
for (i=0; i<nrLini; i++)
{
m[i] = malloc(nrColoane * sizeOfElement);
if (m[i] == NULL)
{
while (i-- > 0)
free(m[i]);
free(m);
return NULL;
}
}
return m;
}
答案 1 :(得分:4)
[不是问题的答案,而是其他人给出的正确答案的缩进用法]
以void
数组的形式访问int
指针数组,执行此操作
int **m = (int **)mdeclaraMatrice(n,m,sizeof(int));
不正确,根据C标准,只有void*
正确转换为任何其他指针,void**
并非必需。所以它应该正确
void ** ppv = mdeclaraMatrice(n,m,sizeof(int));
int * pi = *ppv; /* Please note, there is NO casting necessary here! */
然后像这样访问成员:
pi[0] = 42
pi[1] = 43;
...
这与做
相同*((int *) (pi + 0)) = 42;
*((int *) (pi + 1)) = 43;
这确实没有意义,因为pi
已经是int*
,因此完全正确的方法(也考虑到第二维)将是:
((int *)(ppv[0]))[0] = 42;
((int *)(ppv[0]))[1] = 43;
可以通过定义宏来使其可用:
#define GENERIC_ARRAY_ELEMENT(type, address, r, c) \
((type *)(address[r]))[c]
GENERIC_ARRAY_ELEMENT(int, ppv, 0, 0) = 42;
GENERIC_ARRAY_ELEMENT(int, ppv, 0, 1) = 43;
答案 2 :(得分:3)
我将解决分配一个void指针数组然后将它们解释为int指针数组的问题。
int **nope = (int **)mdeclaraMatrice(n,m,sizeof(int));
即使假设分配完全正确,nope
的赋值和后来的使用也是未定义的行为。 void**
和int**
具有不兼容的类型。
您可以做的是以下内容。将void指针逐个分配给int指针数组。
void** arrp = mdeclaraMatrice(n,m,sizeof(int));
int* arr[n] ;
for( size_t i = 0 , i < n ; i++ )
arr[i] = arrp[i] ;
然后使用arr
数组,当你想释放内存时,释放原始指针:
free( arrp ) ;
答案 3 :(得分:2)
问题出现在这一行:
*(m + (i*4)) = malloc(nrColoane * sizeOfElement);
您必须知道,在向地址添加号码时,地址将以次的数量递增,地址所指向的对象的大小。因此,如果您的指针指向大小为4个字节的对象,并且向其添加1,则地址将自动增加4,不增加1.因此您应该放弃{{1 }}
此外,在分配空间时使用*4
运算符,因为地址(以及指针)在不同的处理器体系结构上可以有不同的大小。
答案 4 :(得分:2)
实际上,如果你知道C99强大的VLA功能,你甚至不需要你的通用2D阵列功能。要分配真正的2D数组(不需要索引数组),只需执行以下操作:
int (*twoDIntArray)[width] = malloc(height*sizeof(*twoDIntArray));
那就是它。访问同样简单:
twoDIntArray[line][column] = 42;
在此代码中,twoDIntArray
是指向width
整数数组的指针。 malloc()
调用只为height
这样的行数组分配足够的空间。当您执行指针算术twoDIntArray[line]
时,将line
行数组的大小添加到指针,这将生成相应行数组的地址。然后,该行数组由第二个数组下标[column]
索引。
毋庸置疑,释放这样一个阵列同样重要:
free(twoDIntArray);