我试图从一个函数返回一个连续的内存分配数组,但是我一直在接收错误。
编译器返回警告return from incompatible pointer type [-Wincompatible-pointer-types]
有人可以告诉我我在做什么错吗?
int *test() {
size_t rows, cols;
// assign rows and cols
rows = 3;
cols = 3;
int count = 0;
int (*arr)[cols] = malloc(sizeof *arr * rows);
if (arr) {
// do stuff with arr[i][j]
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; j++) {
arr[i][j] = count;
count++;
}
/* code */
}
}
return arr;
}
int main() {
size_t rows, cols;
// assign rows and cols
rows = 3;
cols = 3;
int count = 0;
int (*arr)[cols] = malloc(sizeof *arr * rows);
arr = test();
int i = 0;
int j = 0;
for (i = 0; i < rows; ++i) {
for (j = 0; j < 3; ++j)
printf("%d ", arr[i][j]);
printf("\n");
}
free(arr);
}
它应该返回2D数组,但返回错误,并且正在Ubuntu上使用gcc
答案 0 :(得分:0)
您的分配功能很好,除了一些细节:
rows
和cols
作为参数传递size_t
和i
使用类型j
,并迭代到rows
和cols
而不是硬编码边界。malloc(sizeof *arr * rows);
中使用括号以提高可读性:
malloc(sizeof(* arr)*行); &arr[0][0]
或arr[0]
以确保类型正确。问题是您无法将test
的返回类型定义为指向参数第二维的2D数组的指针。因此,分配arr = test();
上的类型错误无法修复。您可以通过将返回值强制转换为(int (*)[cols])
或简单地使用(void *)
来解决此缺点。
这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
int *test(size_t rows, size_t cols) {
int (*arr)[cols] = malloc(sizeof(*arr) * rows);
if (arr) {
// initialize the matrix
size_t count = 0;
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++) {
arr[i][j] = count;
count++;
}
/* code */
}
return &arr[0][0];
}
return NULL;
}
int main() {
// assign rows and cols
size_t rows = 3;
size_t cols = 3;
int (*arr)[cols] = (int (*)[cols])test(rows, cols);
if (arr) {
for (size_t i = 0; i < rows; i++) {
for (size_t j = 0; j < cols; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
free(arr);
}
return 0;
}
输出:
0 1 2 3 4 5 6 7 8
答案 1 :(得分:0)
如果全部,您需要的是
从函数返回连续的内存分配数组
您可以忽略此答案。
如果您要使用动态分配的连续内存块为二维容器(如矩阵)建模,则可以定义struct
并将其传递给周围:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct {
int rows, cols;
int values[]; // I'm using a Flexible Array Member here.
} iMat;
iMat *alloc_matrix(int rows, int columns)
{
assert(rows > 0 && columns > 0);
iMat *tmp = malloc(sizeof *tmp + sizeof *(tmp->values) * rows * columns);
if (tmp)
{
tmp->rows = rows;
tmp->cols = columns;
}
return tmp;
}
void fill_matrix_iota(iMat *m, int start)
{
if ( m )
for (size_t i = 0, n = m->rows * m->cols; i < n; ++i)
m->values[i] = start + i;
}
void print_matrix(iMat *m, int width)
{
if (m)
{
for (int i = 0, k = 0; i < m->rows; ++i)
{
for(int j = 0; j < m->cols; ++j, ++k)
{
printf("%*.d", width, m->values[k]);
}
putchar('\n');
}
}
}
iMat *make_transposed(iMat *m)
{
if ( !m )
return NULL;
iMat *tmp = alloc_matrix(m->cols, m->rows);
if ( tmp )
{
for (int i = 0; i < m->rows; ++i)
{
for(int j = 0; j < m->cols; ++j)
{
tmp->values[j * m->rows + i] = m->values[i * m->cols + j];
}
}
}
return tmp;
}
int main(void)
{
iMat *a = alloc_matrix(3, 4);
if (!a)
exit(EXIT_FAILURE);
fill_matrix_iota(a, 1);
print_matrix(a, 3);
iMat *b = make_transposed(a);
if (!b)
{
free(a);
exit(EXIT_FAILURE);
}
putchar('\n');
print_matrix(b, 3);
free(b);
free(a);
return EXIT_SUCCESS;
}