我正在尝试编写一个函数,以指定的大小(以字节为单位)转发指针。
void
increment_ptr(void **_ptr, int size){
*_ptr = (char *)(*_ptr) + size;
}
int
main(int argc, char **argv){
int arr[] = {11,20};
printf("%d\n", arr[0]);
increment_ptr((void **)&arr, sizeof(int));
printf("%d\n", arr[0]);
return 0;
}
我得到的输出是:
vm@vm:~$ ./a.out
11
15
我期待输出为11和20。
有人可以帮忙吗?
答案 0 :(得分:4)
arr
不是您可以更改的普通变量。它不是指针 - 它的类型是int[2]
。
试试这段代码:
#include <stdio.h>
void
increment_ptr(void **_ptr, int size){
*_ptr = (char *)(*_ptr) + size;
}
int
main(int argc, char **argv){
int arr[] = {11,20};
int* arr1 = arr;
printf("arr is %p\n", (void*)arr);
printf("arr1 is %p\n", (void*)arr1);
printf("arr gives %d\n", arr[0]);
printf("arr1 gives %d\n", arr1[0]);
increment_ptr((void **)&arr, sizeof(int));
increment_ptr((void **)&arr1, sizeof(int));
printf("arr is %p\n", (void*)arr);
printf("arr1 is %p\n", (void*)arr1);
printf("arr gives %d\n", arr[0]);
printf("arr1 gives %d\n", arr1[0]);
return 0;
}
可能的输出:
arr is 0xfff1d1b8
arr1 is 0xfff1d1b8
arr gives 11
arr1 gives 11
arr is 0xfff1d1b8 // Notice arr isn't changed
arr1 is 0xfff1d1bc // arr1 works as expected
arr gives 15
arr1 gives 20
换句话说:你不能推进这种阵列的基地址
您可能还会发现此代码很有趣:
#include <stdio.h>
int main(int argc, char **argv){
int arr[2] = {11,20};
printf("arr is %p\n", (void*)arr);
printf("arr is %p\n", (void*)&arr);
return 0;
}
可能的输出:
arr is 0061FED8
&arr is 0061FED8
请注意如何将arr
打印为指针与打印&arr
那么代码中发生的是数字11
(又名arr [0])被读作指针(转换为char *),然后添加4
(所以你有{{} 1}})覆盖当前15
。注意:此结果表明指针和11
都是系统上的4个字节。
答案 1 :(得分:2)
代码
int arr[2];
声明一个内存空间。因此,当您获取其地址时,它将返回此内存空间的基址,该地址与arr。
相同这与声明指针的情况不同。指针是保存地址的变量,但数组只是内存空间。
答案 2 :(得分:0)
当你声明一个变量(数组与否)时,它的地址在该变量的生命周期的其余部分没有变化。无法将变量移动到新地址。
您的代码只会导致未定义的行为(严格别名冲突 - *_ptr
使用类型void *
的左值来访问声明为int
的内存。)