用C语言中的结构传递数组及其长度

用C语言中的结构传递数组及其长度,c,arrays,pointers,memory,struct,C,Arrays,Pointers,Memory,Struct,我试图返回一个数组及其从一个函数到另一个函数的长度。我了解到,我不能简单地用sizeof()确定父函数中返回数组的大小,因为数组作为参数传递时会简化为指针。我发现我可以将数组指针和大小返回给父函数,所以这就是我要尝试的 数组的类型是unsigned char*,因为我正在处理内存地址。数组在发送到结构之前看起来很好。一旦我尝试通过父函数中的struct引用数组,所有内存地址都会被拆分。我有一种预感,结构填充可能是问题所在 我写了一些照片来分析到底发生了什么 struct arrayPasser{

我试图返回一个数组及其从一个函数到另一个函数的长度。我了解到,我不能简单地用sizeof()确定父函数中返回数组的大小,因为数组作为参数传递时会简化为指针。我发现我可以将数组指针和大小返回给父函数,所以这就是我要尝试的

数组的类型是unsigned char*,因为我正在处理内存地址。数组在发送到结构之前看起来很好。一旦我尝试通过父函数中的struct引用数组,所有内存地址都会被拆分。我有一种预感,结构填充可能是问题所在

我写了一些照片来分析到底发生了什么

struct arrayPasser{
    int length;
    unsigned char *arr;
};

unsigned char *arr[arrLength]; /*array of pointers*/

/*filling out the array with addresses*/

struct arrayPasser pass;

pass.length=arrLength;
pass.arr=&arr;

printf("pass.arr: %#x\n", pass.arr); /*print array location*/

printf("*(&arr): %#x\n", *(&arr));
printf("**(&arr): %#x\n", **(&arr));

/*original array*/
printf("arr[0] %#x\n", arr[0]);     
printf("arr[1] %#x\n", arr[1]);
printf("arr[2] %#x\n", arr[2];

/*referencing array through struct*/
printf("0 offset: %#x\n", *pass.arr);
printf("1 offset: %#x\n", *(pass.arr+1));
printf("2 offset: %#x\n", *(pass.arr+2));
printf("3 offset: %#x\n", *(pass.arr+3);
printf("4 offset: %#x\n", *(pass.arr+4));
printf("5 offset: %#x\n", *(pass.arr+5));
printf("6 offset: %#x\n", *(pass.arr+6));
printf("7 offset: %#x\n", *(pass.arr+7));

printf("pass.arr[0]: %#x\n", pass.arr[0]);
printf("pass.arr[1]: %#x\n", pass.arr[1]);
printf("pass.arr[2]: %#x\n", pass.arr[2]);
printf("pass.arr[3]: %#x\n", pass.arr[3]);
printf("pass.arr[4]: %#x\n", pass.arr[4]);
printf("pass.arr[5]: %#x\n", pass.arr[5]);
printf("pass.arr[6]: %#x\n", pass.arr[6]);
printf("pass.arr[7]: %#x\n", pass.arr[7]);
输出(请注意,arr[0]是一个完整的32位地址,但pass.arr[0]只是32位地址的一个字节):


unsigned char*arr[arrLength]
是指针数组,但由于数组本质上是指针,变量
arr
指向数组中的第一个指针,因此它相当于
unsigned char**arr

printf("pass.arr[0]: %#x\n", pass.arr[0]);
printf("pass.arr[1]: %#x\n", pass.arr[1]);
printf("pass.arr[2]: %#x\n", pass.arr[2]);
printf("pass.arr[3]: %#x\n", pass.arr[3]);
但是
unsigned char*arr
是指向
char
的指针,但不是指向指针的指针。换句话说,它是字符数组,而不是指针数组

将您的结构声明为:

struct arrayPasser{
    int length;
    unsigned char **arr;
};
当您取消对
arr
的引用时,您将得到一个指针而不是char

printf("pass.arr[0]: %#x\n", pass.arr[0]);
printf("pass.arr[1]: %#x\n", pass.arr[1]);
printf("pass.arr[2]: %#x\n", pass.arr[2]);
printf("pass.arr[3]: %#x\n", pass.arr[3]);
让我试着解释一下为什么你的代码不起作用。考虑这个数组:

unsigned char *arr[3]
arr[0] = 0x4affb000;
arr[1] = 0x4affd000;
arr[2] = 0x4affc000;
执行此操作时,您输入的数据会像下面这样放置在内存中:

00 b0 ff 4a   00 d0 ff 4a   00 c0 ff 4a
^             ^             ^
|             |             |
arr           arr + 1       arr + 2
points here   points here   points here
存储在内存中的整数具有较小的端字节顺序,因此它们的字节是反向的

当您执行
arr[0]
时,您会得到
0x4affb000
,因为sizeof(arr[0])是4,因此您会得到4个字节

然后,您可以这样做:

unsigned char *arr2 = arr;  /* which is equal to arr2 = &arr */
内存不会更改,但指针的行为方式会更改。现在它是指向
char
的指针,而不是指向指针的指针,因此指针引用的对象的大小现在是1而不是4。换句话说,
arr
arr2
都指向相同的内存位置,但是
arr
元素的大小是4,
arr2
元素的大小是1

以下是您获得的
arr2

00 b0 ff 4a   00 d0 ff 4a   00 c0 ff 4a
^  ^  ^  ^
|  |  |  +--arr2 + 3
|  |  +--arr2 + 2
|  +--arr2 + 1
+--arr2

现在,当您执行
arr2[0]
时,您会得到
0x00
,因为sizeof(arr2[0])是1个字节。

unsigned char*arr[arrllength]
是指针数组,但由于数组本质上是指针,因此变量
arr
指向数组中的第一个指针,因此,它相当于
无符号字符**arr

printf("pass.arr[0]: %#x\n", pass.arr[0]);
printf("pass.arr[1]: %#x\n", pass.arr[1]);
printf("pass.arr[2]: %#x\n", pass.arr[2]);
printf("pass.arr[3]: %#x\n", pass.arr[3]);
但是
unsigned char*arr
是指向
char
的指针,但不是指向指针的指针。换句话说,它是字符数组,而不是指针数组

将您的结构声明为:

struct arrayPasser{
    int length;
    unsigned char **arr;
};
当您取消对
arr
的引用时,您将得到一个指针而不是char

printf("pass.arr[0]: %#x\n", pass.arr[0]);
printf("pass.arr[1]: %#x\n", pass.arr[1]);
printf("pass.arr[2]: %#x\n", pass.arr[2]);
printf("pass.arr[3]: %#x\n", pass.arr[3]);
让我试着解释一下为什么你的代码不起作用。考虑这个数组:

unsigned char *arr[3]
arr[0] = 0x4affb000;
arr[1] = 0x4affd000;
arr[2] = 0x4affc000;
执行此操作时,您输入的数据会像下面这样放置在内存中:

00 b0 ff 4a   00 d0 ff 4a   00 c0 ff 4a
^             ^             ^
|             |             |
arr           arr + 1       arr + 2
points here   points here   points here
存储在内存中的整数具有较小的端字节顺序,因此它们的字节是反向的

当您执行
arr[0]
时,您会得到
0x4affb000
,因为sizeof(arr[0])是4,因此您会得到4个字节

然后,您可以这样做:

unsigned char *arr2 = arr;  /* which is equal to arr2 = &arr */
内存不会更改,但指针的行为方式会更改。现在它是指向
char
的指针,而不是指向指针的指针,因此指针引用的对象的大小现在是1而不是4。换句话说,
arr
arr2
都指向相同的内存位置,但是
arr
元素的大小是4,
arr2
元素的大小是1

以下是您获得的
arr2

00 b0 ff 4a   00 d0 ff 4a   00 c0 ff 4a
^  ^  ^  ^
|  |  |  +--arr2 + 3
|  |  +--arr2 + 2
|  +--arr2 + 1
+--arr2

现在,当您执行
arr2[0]
时,您会得到
0x00
,因为sizeof(arr2[0])是1个字节。

unsigned char*arr[arrllength]
是指针数组,但由于数组本质上是指针,因此变量
arr
指向数组中的第一个指针,因此,它相当于
无符号字符**arr

printf("pass.arr[0]: %#x\n", pass.arr[0]);
printf("pass.arr[1]: %#x\n", pass.arr[1]);
printf("pass.arr[2]: %#x\n", pass.arr[2]);
printf("pass.arr[3]: %#x\n", pass.arr[3]);
但是
unsigned char*arr
是指向
char
的指针,但不是指向指针的指针。换句话说,它是字符数组,而不是指针数组

将您的结构声明为:

struct arrayPasser{
    int length;
    unsigned char **arr;
};
当您取消对
arr
的引用时,您将得到一个指针而不是char

printf("pass.arr[0]: %#x\n", pass.arr[0]);
printf("pass.arr[1]: %#x\n", pass.arr[1]);
printf("pass.arr[2]: %#x\n", pass.arr[2]);
printf("pass.arr[3]: %#x\n", pass.arr[3]);
让我试着解释一下为什么你的代码不起作用。考虑这个数组:

unsigned char *arr[3]
arr[0] = 0x4affb000;
arr[1] = 0x4affd000;
arr[2] = 0x4affc000;
执行此操作时,您输入的数据会像下面这样放置在内存中:

00 b0 ff 4a   00 d0 ff 4a   00 c0 ff 4a
^             ^             ^
|             |             |
arr           arr + 1       arr + 2
points here   points here   points here
存储在内存中的整数具有较小的端字节顺序,因此它们的字节是反向的

当您执行
arr[0]
时,您会得到
0x4affb000
,因为sizeof(arr[0])是4,因此您会得到4个字节

然后,您可以这样做:

unsigned char *arr2 = arr;  /* which is equal to arr2 = &arr */
内存不会更改,但指针的行为方式会更改。现在它是指向
char
的指针,而不是指向指针的指针,因此指针引用的对象的大小现在是1而不是4。换句话说,
arr
arr2
都指向相同的内存位置,但是
arr
元素的大小是4,
arr2
元素的大小是1

以下是您获得的
arr2

00 b0 ff 4a   00 d0 ff 4a   00 c0 ff 4a
^  ^  ^  ^
|  |  |  +--arr2 + 3
|  |  +--arr2 + 2
|  +--arr2 + 1
+--arr2

现在,当您执行
arr2[0]
时,您会得到
0x00
,因为sizeof(arr2[0])是1个字节。

unsigned char*arr[arrllength]
是指针数组,但由于数组本质上是指针,因此变量
arr
指向数组中的第一个指针,因此,它相当于
无符号字符**arr

printf("pass.arr[0]: %#x\n", pass.arr[0]);
printf("pass.arr[1]: %#x\n", pass.arr[1]);
printf("pass.arr[2]: %#x\n", pass.arr[2]);
printf("pass.arr[3]: %#x\n", pass.arr[3]);
但是
unsigned char*arr
是指向
char
的指针,但不是指向指针的指针。换句话说,它是字符数组,而不是指针数组

D