为什么添加指针+ = work,但指针+ 1不是?

时间:2015-01-31 20:45:38

标签: c pointers pointer-arithmetic

我正在为一个数组分配内存,但我正在移动指针向前指向一点点。访问元素工作正常。它开始产生释放已分配内存的问题。 Malloc抱怨从​​未分配被释放的指针。这个简化的代码可以重现这个问题:

int *pointer = malloc(sizeof(int)) + 1;
free(pointer - 1);

我开始尝试,发现代码的这种微小变化可以发挥作用。

int *pointer = malloc(sizeof(int));
pointer += 1;
free(pointer - 1);

+ =做什么不同只是在指针中添加1,malloc返回一行?

3 个答案:

答案 0 :(得分:45)

malloc的返回类型是void *,根据标准,它不能用于指针算法。

然而,有一个GNU扩展,将sizeof(void)视为1,这就是您的第一个片段编译的原因。稍后,pointer - 1减去sizeof(int)而不是1,因此指针不匹配。

执行指针运算时应用的实际偏移量总是取决于指针的类型。由于pointerint *,因此实际的偏移量将乘以sizeof(int)。如果sizeof(void)1或者char *指针(sizeof(char) == 1),则不会发生乘法。

答案 1 :(得分:5)

指针算法可以使用++=来完成。它与产生的错误无关。

malloc返回void *类型。 C标准说:

C11:6.2.5类型(第19页):

  

void类型包含一组空值;这是一个无法完成的不完整类型

6.5.6加法运算符(p2):

  

另外,两个操作数都应具有算术类型,或者一个操作数应为指向完整对象类型的指针,另一个操作数应具有整数类型。 (递增相当于添加1.)

void *指向不完整类型的指针。因此,不会使用void *类型执行添加。这就是为什么

int *pointer = malloc(sizeof(int)) + 1;  

错误,导致执行free(pointer - 1);时出现运行时错误。

答案 2 :(得分:0)

看到其他答案,将代码更改为

int *pointer = (int *)malloc(sizeof(int));

int * pointer = new int[1];

可以让你做你想做的事。