我正在尝试创建一个函数,该函数获取列和行的数目(宽度和高度),构建2D矩阵,然后将Matrix [0] [0]的地址返回到原始调用方中的指针功能。
int **allocateMatrix(int width, int height) // function that allocate
//memory for 2D matrix and check that memory allocation was successful
{
int **Matrix;
int row;
Matrix = (int**)malloc(sizeof(int*)*height);
if (!Matrix)
{
printf("failed to allocate memory. this program is over.\n");
exit(1);
}
for (row = 0; row < height; row++)
{ Matrix[row] = (int*)malloc(sizeof(int)*width);
if (!Matrix[row])
{
printf("failed to allocate memory. this program is over.\n");
exit(1);
}
}
return Matrix;
}
在分配过程中,我通过调试器监视了整个过程,似乎创建了我想要的太大的矩阵,并且通常出现了意外情况。 例如:高度= 5,宽度= 5, 尽管Matrix [0] [30]-存在并且可以访问。
此外,我不确定返回的地址。
答案 0 :(得分:1)
您的分配没有问题。在C语言中,如果您走出了界限,并且很幸运,您会收到一个分段错误信号,并且该程序终止(如果您尚未为此信号安装特定的信号处理程序),但是如果您到达某个有效内存,则可以访问记忆力和破坏某些东西的风险。
就像其他人在评论中说的那样,C不会捕获编码错误,但是如果您使用标志-Wall -pedantic -g
进行编译,则编译器将在某些内容关闭时生成一些警告,有时甚至会提示您如何解决错误。还了解如何使用valgrind
。
答案 1 :(得分:1)
您的分配方案没有错,但是有许多改进尚待完成。如果您的调试器报告可以到达30个元素的行,则您查看信息的方式有问题。
首先,无需强制返回malloc
,这是不必要的。参见:Do I cast the result of malloc?。
在分配函数中避免使用exit
。调用者应该可以选择适当地处理分配失败的问题,而不是在此时退出程序。 exit
有效时,它严重限制了您处理故障的选项。而是在成功时返回有效的指针,否则返回NULL
,然后由调用方处理错误。如果分配失败,则由您free()
之前的所有分配决定,然后返回NULL
。
请考虑使用calloc
为matrix[row]
分配存储空间。 calloc
将分配为零的所有字节有效地初始化为每一行的每个元素,以0
防止在返回后无意访问未初始化元素时发生未定义行为。
将所有片段放在一起,您可以执行以下操作:
/* allocatematrix allocates storage for a width x height matrix of type int.
* all elements are initialized zero. on success returns a pointer to pointer
* to type, otherwise all allocations are freed and NULL is returned.
*/
int **allocatematrix (int width, int height)
{
int **matrix;
int row; /* declare row in for loop declaration, unless c89 support needed */
matrix = malloc (height * sizeof *matrix); /* allocate pointers */
if (!matrix) { /* validate */
perror ("malloc-matrix"); /* malloc failure set errno, use it */
return NULL; /* evaluate return in caller */
}
for (row = 0; row < height; row++) { /* for each pointer */
matrix[row] = calloc (width, sizeof *matrix[row]); /* alloc rows */
if (!Matrix[row]) { /* validate */
perror ("calloc-matrix[row]"); /* ditto for calloc */
while (row--) /* loop over previous rows */
free (matrix[row]); /* free previously allocated rows */
free (matrix); /* free pointers */
return NULL; /* evaluate return in caller */
}
}
return matrix; /* return initial pointer address */
}
(注意:,虽然不是错误,但C通常避免使用camelCase
或MixedCase
变量和函数名,而推荐使用所有小写字母< / em>保留大写名称供宏和常量使用。这是样式问题-完全由您决定)
(也请注意::使用perror
代替printf
进行错误报告。当函数将errno
设置为失败时,perror
应该使用。此外,它已经在stderr
上提供了输出。如果处理未设置errno
的故障,则使用fprintf
(如果需要转换)或{{1 }},然后在fputs
而不是stderr
上报告错误
仔细检查一下,如果还有其他问题,请告诉我。