我有点困惑。下面是一个非常简单的例子:
#include <stdlib.h>
typedef struct
{
unsigned char one: 1;
unsigned char two:1;
unsigned char three: 1;
unsigned char four: 1;
} nibble_bits;
typedef union
{
unsigned char all : 4;
nibble_bits bits;
} nibble;
void initArr(nibble ** arrLoc, unsigned int size)
{
nibble * start = arrLoc[0];
int i =0;
for (i=0; i<size; i++)
{
start[i].all = 0;
}
}
int main()
{
nibble * fourNibbles = (nibble *) malloc(4 * sizeof(nibble));
initArr(&fourNibbles,4);
}
这个编译很好,没有任何警告。但是,当我更改main中的第一行时:
nibble * fourNibbles = (nibble *) malloc(4 * sizeof(nibble));
为:
nibble fourNibbles[4];
我得到以下内容:
警告:main.c:在函数'main'中: main.c:150:警告:从不兼容的指针类型
传递'initArr'的参数1运行后,我收到“总线错误10”。
在我看来,线条正在做同样的事情,除了malloc为堆上的数组分配空间并且数组声明在堆栈上。但是(我认为)无论哪种方式,“fourNibbles”都是“指向半字节”的类型,因此“fourNibbles”的地址将指向指向半字节的指针(半字节**)。
我在这里缺少什么?
答案 0 :(得分:3)
这些甚至都不一样。此
nibble * fourNibbles = (nibble *) malloc(4 * sizeof(nibble));
声明一个指针fourNibbles
,而这个
nibble fourNibbles[4];
声明一个数组。数组和指针是两个完全不同的东西,它们(在对象级别)没有任何共同之处。尝试在对象上下文中交替使用它们(如&
运算符)只会导致灾难。有关此主题的大量信息,请参阅SO(搜索“数组指针差异”)以及[事实上的标准] C常见问题解答:http://c-faq.com/aryptr/index.html
尽管如此,还有另一件事引起了人们的注意。你的功能
void initArr(nibble ** arrLoc, unsigned int size)
专门针对第一个变体而定制,因为它需要指向指针的指针作为其第一个参数。如果你试图强制指向数组的指针到第一个参数(你已经有机会亲自观察),它将无法工作。
但是,真正的问题是为什么你的initArr
函数是以如此奇怪的方式编写的。这个序列
void initArr(nibble ** arrLoc, unsigned int size)
{
...
nibble * start = arrLoc[0];
...
start[i].all = 0;
看起来很不寻常。为什么要将指针传递给指针而不是普通的单级指针?例如。你可以简单地做
void initArr(nibble *start, unsigned size)
{
unsigned i;
for (i = 0; i < size; ++i)
start[i].all = 0;
}
此版本将被称为
initArr(fourNibbles,4); /* note: no `&` operator */
它将兼容malloc
- ed数组和显式声明的数组。
P.S。在C语言中,malloc
的更好的习语是
nibble * fourNibbles = malloc(4 * sizeof *fourNibbles);
请注意,在此变体中,类型名称nibble
仅提及一次。
答案 1 :(得分:2)
您遗漏的是,数组的地址与在表达式中使用的纯数组名称的指针具有不同的类型。
那是:
int *a1 = ...;
int a2[] = { ... };
some_func(&a1);
some_func(&a2);
除非some_func()
期望void *
,否则无效。第一个调用传递int **
- 指向int
的指针;第二个调用传递int (*)[]
- 一个指向int
数组的指针。从数组中删除&
。
但是,在您的代码中,问题更复杂。因为函数需要nibble **
,所以您遇到了问题。你应该做的是传递nibble *
:
void initArr(nibble *arrLoc, unsigned int size)
{
for (unsigned int i = 0; i < size; i++)
start[i].all = 0;
}
int main(void)
{
nibble *fourNibbles_1 = (nibble *) malloc(4 * sizeof(nibble));
nibble fourNibbles_2[4];
initArr(fourNibbles_1, 4);
initArr(fourNubbles_2, 4);
initArr(&fourNubbles_2[0], 4);
}
你的实际代码正在做一些非常奇怪的事情。它所造成的伤害程度可能取决于指针与nibble
的比较大小。