为何使用void**指针替代int**指针时程序无法正常运行?
为什么用
void**声明多维矩阵指针会导致程序无法运行? 把rows声明为void**后程序无法运行,核心原因是C语言中void是不完整类型,没有确定的内存大小,而多维数组的下标访问、赋值操作都依赖于明确的类型大小,具体问题如下:
1. 二级指针的下标访问无法计算内存偏移
当你使用rows[i][j]这种下标语法时,编译器会把它拆解为两步内存访问:
- 第一步:
rows[i]等价于*(rows + i),这一步对于void**是合法的——因为rows是指向void*的指针,i的偏移量是i * sizeof(void*),编译器知道void*的大小(和系统指针宽度一致,比如64位系统是8字节)。 - 第二步:
rows[i][j]等价于*(rows[i] + j),这里就出问题了:rows[i]是void*类型,而C语言不允许对void*进行算术运算——因为void没有确定的大小,编译器不知道j对应的内存偏移量是多少(比如如果是int*,偏移量是j * sizeof(int),但void没有这个值)。
对比你原来的int** rows:rows[i]是int*,rows[i]+j的偏移量是j*sizeof(int),编译器能正确计算,所以下标访问合法。
2. 类型不匹配的赋值错误
语句rows[i][j] = i + j;试图把一个int值赋值给void**指向的内存位置,但void**的二级指针指向的是void*类型的对象,不是int类型。编译器会直接抛出类型不兼容的错误,因为C语言不允许隐式地把int值赋值给void类型的内存区域。
正确的做法
如果你要处理int类型的多维矩阵,就用int**作为指针类型(也就是你代码中注释掉的正确写法)。如果需要实现通用的多维矩阵处理,你可以用void*作为一级指针,然后手动计算内存偏移(但需要额外记录元素大小和维度信息),示例如下:
#include <stdio.h> #include <stdlib.h> int main() { int n = 0; printf("The size of matrix\n"); scanf("%d", &n); // 用void*存储整个矩阵的内存,手动计算偏移 void* matrix = malloc(n * n * sizeof(int)); int i, j; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { // 手动计算int类型的偏移位置 int* pos = (int*)matrix + i * n + j; *pos = i + j; printf("%d ", *pos); } printf("\n"); } free(matrix); return 0; }
内容的提问来源于stack exchange,提问作者JOHN BOURAS
相关产品推荐
相关产品推荐

