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