2017-01-03 61 views
-1

我犯了一个函数来创建一个连续的二维阵列是这样的:Ç毗连二维阵列的通用功能指针运算

void** create2DArray(int row, int col, size_t s) { 
    void *pool = malloc(s * row * col); 
    void **array = malloc(s * row); 

    if(pool==NULL || array==NULL) return NULL; 

    for(int i=0;i<row;i++) { 
     array[i] = pool + i * col * s; 
    } 

    return array; 
} 

功能上面使用这样的:

int **edge_matrix = create2DArray(num_vertices, num_vertices, sizeof(int)); 

它的工作原理没有问题。但是有一天,我还以为我犯了一个错误,我改了一行代码与此:

array[i * s] = pool + i * col * s; 

由于指针运算法则,无效*总是会增加我* 1个字节。我改变了它,所以它会像通常的指针算术一样增加I * s字节,用于非void *类型。但为什么第一个工作,而第二个不工作?

+3

因为'无效**'是*不*'无效*'。 '* array'具有'void *'类型(即是指针)而不是'void'。你也可能想要实现更强大的错误检查。 –

+0

如果'pool'或'array'分配失败而另一个成功,则永远不会分配第一个内存,并最终导致内存泄漏。授予这是一个边缘案例。 –

+0

代码中没有二维数组,也没有任何指向一个的数组!像'int **'(更糟糕的是,'void **')是一个完全不同的数据结构,不要太喜欢使用类型转换!这样的代码很难维护和理解,它也容易出现类型错误 – Olaf

回答

0

您的函数不会创建二维数组,也不会连续存储内存。你不应该使用指向指针的指针,因为指针指针和二维数组之间没有关系。这是一个常见的误解。

此外,C语言不允许在void指针上进行指针运算。有些编译器支持将其作为字符类型的指针运算的非标准扩展。

无论如何,你甚至不需要指针算术。简单地做:

void* create2DArray (size_t row, size_t col, size_t item_size) 
{ 
    return malloc (item_size * row * col); 
} 

或者,更意味深长:

void create2DArray (size_t row, size_t col, (type** arr_ptr)[row][col]) 
{ 
    *arr_ptr = malloc (sizeof type[row][col]); 
} 


// caller: 
type (*array)[row][col]; 
create2DArray(row, col, &array); 

完整的例子在这里:Set pointers on Dynamic Matrix