我有一个将void指针指向另一个struct指针的问题。 我的输入参数在函数semaphoreCreateBinary中更改,但是当它返回main时它再次为空。我必须做某种演员,但我似乎无法让它发挥作用。
我将包含我认为有必要了解我的问题的代码:
来自我的头文件。
typedef struct semaphoreStruct
{
int smValue;
tcbExtS *smHolder;
int smCeiling;
}semaS;
typedef void * SemaphoreHandle;
在我的C档案中
unsigned int semaphoreCreateBinary(void *ro_Handle,unsigned int i_InitialValue)
{
semaS *Semaphorehandle1;
Semaphorehandle = malloc (sizeof(*Semaphorehandle));
Semaphorehandle1->smValue = i_InitialValue;
ro_Handle = Semaphorehandle1; //seems to get the correct value
return resultUnInt;
}
int main(void)
{
SemaphoreHandle s1vPtr;
semaphoreCreateBinary(&s1vPtr,0);
int IV = s1vPtr->smValue//s1vPtr is empty again here
}
有任何建议如何更正?
编辑: 即使我将论点作为地址传递给: semaphoreCreateBinary(安培; s1vPtr,0); 这是行不通的。 我无法更改输入类型,因为我们从老师那里得到了API-Spec,否则我会改变它。
答案 0 :(得分:2)
在C中,参数按值传递给函数。因此,您只更改函数内的值。另外,还有一个错误:你没有分配Semaphorehandle1
。所以,会有段错误。这是正确的:
unsigned int semaphoreCreateBinary(void **ro_Handle,unsigned int i_InitialValue)
{
semaS *Semaphorehandle1 = malloc(sizeof(semaS));
Semaphorehandle1->smValue = i_InitialValue;
*ro_Handle = Semaphorehandle; //seems to get the correct value
return resultUnInt;
}
使用后不要忘记释放内存。
答案 1 :(得分:1)
这有效:
unsigned int semaphoreCreateBinary(void *ro_Handle, unsigned int i_InitialValue)
{
semaS *Semaphorehandle1 = malloc(sizeof(semaS));
Semaphorehandle1->smValue = i_InitialValue;
*(semaS**)ro_Handle = Semaphorehandle1;
}
int main(void)
{
semaS* s1vPtr;
semaphoreCreateBinary(&s1vPtr, 1);
int IV = s1vPtr->smValue;
free(s1vPtr);
printf("%d\n", IV);
}
说明:有两个重要的见解需要理解为什么这是一个有用的解决方案 - 作为未来的软件开发人员,您需要自己获得这些见解:
semaS*
指针(让它指向新malloc
ed内存位置)。因此,如果您要修改semaS*
,则必须将semaS**
传递给该函数。void*
强制转换为任何指针类型,包括指针指向指针。另请注意,您的初始malloc
尺寸错误。由于您要分配新的semaS
结构,因此必须malloc
一个大小为size(semaS)
的内存块(您malloc
编写一个指针大小的内存块)。不幸的是,使用任何其他块大小都不会在C中引发编译器警告或错误。但它会浪费内存(如果块大小太大)或导致内存损坏(如果块大小太小)。
答案 2 :(得分:0)
在您的代码中,semaphoreCreateBinary()
函数
ro_Handle = Semaphorehandle1;
不符合您的目的。指针ro_Handle
本身通过pass-by-value传递给函数,因此您无法从函数中更改指针本身,并期望它在函数外部反映该更改。您可以更改指针指向的值,它将维持,但不是指针。
如果你想更改指针,你需要传递指针的地址,作为指向指针。
话虽如此,
semaS *Semaphorehandle1;
Semaphorehandle1->smValue = i_InitialValue;
是完全错误的,因为此时Semaphorehandle1
未初始化(即,未指向任何有效的内存位置)并尝试取消引用未初始化的指针将导致undefined behavior,从而导致分段错误。您需要先分配适当的内存,然后才能实际继续并取消引用该指针。
答案 3 :(得分:0)
在代码中ro_Handle = Semaphorehandle1;
不会更改main
范围内指针的值,因为指针是semaphoreCreateBinary
范围内的副本(通过值传递)。为了编辑指针的值,您需要一个指向它的指针:
unsigned int semaphoreCreateBinary(void **ro_Handle,unsigned int i_InitialValue) {
...
*ro_Handle = Semaphorehandle1;
然后,您需要将指针的地址传递给函数:
semaphoreCreateBinary(&s1vPtr,0);
答案 4 :(得分:0)
您似乎对指针的工作原理有一些严重的误解。指针是可能存储有效变量的位置的变量,但不必 - 这取决于您是否正确初始化指针。你的行
semaS *Semaphorehandle1;
声明未初始化指针,即指向任意内存位置的指针。下一行
Semaphorehandle1->smValue = i_InitialValue;
然后取消引用未初始化的指针,从而写入任意内存位置 - 这是典型的内存损坏,可能导致整个程序的未定义行为。