=Start=
缘由:
标题其实是个错误的说法,因为在C语言中函数参数是没有数组这一类型的,只是我之前这么以为的而已,在程序中碰到的一个问题,在此记录一下,方便以后参考。
正文:
参考解答:
起因在于如下一段代码:
int get_env_from_pid ( int pid, char environ[]) { char file[PATH_MAX]; snprintf(file, PATH_MAX, "/proc/%d/environ" , pid); int i, r = 0 , fd = open(file, O_RDONLY); memset(environ, 0 , ENV_LEN); // printf("sizeof(environ) = %d\n", sizeof(environ)); // 8 // printf("sizeof(*environ) = %d\n", sizeof(*environ)); // 1 // printf("strlen(environ) = %d\n", strlen(environ)); // 0 if (fd > 0 ) { // r = read(fd, environ, sizeof(environ)); // 错误! r = read(fd, environ, ENV_LEN); close(fd); for (i = 0 ; r > 0 && i < r- 1 ; i++) { if (environ[i] == 0 ) environ[i] = '\n' ; } return 0 ; } return - 1 ; } |
Google了一下,发现下面一段解释:
Function parameters never actually have array type. When the compiler sees
void printarray( double p[], int s )
or even
void printarray( double p[100], int s )
it converts either one to
void printarray( double* p, int s )
So sizeof(p)
is sizeof(double*)
. And yes, you’ll have to pass the size as a parameter.
原因在于,C语言不是一个反射型语言,对象无法自动知道它是什么类型、大小等信息(C is not a reflective language. Objects don’t automatically know what they are.)
But you have many choices:
- Obviously, add a parameter
- Wrap the call in a macro and automatically add a parameter
- Use a more complex object. Define a structure which contains the dynamic array and also the size of the array. Then, pass the address of the structure.
解决办法在于:
- 主动传一个表明该数组大小的参数;
- 将调用放在macro中(让它自动帮你加一个参数传过去);
- 使用一个更复杂的对象/数据结构,其中包含了它的大小等信息;
参考链接:
- https://stackoverflow.com/questions/5493281/c-sizeof-a-passed-array/5493327#5493327
- https://stackoverflow.com/questions/492384/how-to-find-the-sizeof-a-pointer-pointing-to-an-array
=END=