繁体   English   中英

指向结构指针的void指针

[英]void pointer to a struct pointer

将void指针分配给另一个结构指针时遇到问题。 我的输入参数在函数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规范,否则我会更改它。

在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;
}

使用后不要忘记释放内存。

这有效:

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);
}

说明:要理解为什么这是一个有用的解决方案的方法,有两个重要的见解是必要的-作为未来的软件开发人员,您将需要自己获得这些见解:

  1. 在C语言中,如果您希望函数修改某些内容,则必须传递一个指向该内容的指针。 在你的情况,你要修改semaS*指针(让它指向新malloc版内存位置)。 因此,如果要修改semaS* ,则必须将semaS**传递给函数。
  2. void*可以转换为任何指针类型,包括一个指针的指针。

还要注意,您的初始malloc大小是错误的。 由于要分配一个新的semaS结构,你要malloc大小的内存块size(semaS)malloc编一个内存块的指针的大小)。 不幸的是,使用任何其他块大小都不会在C中引发编译器警告或错误。但是,这将浪费内存(如果块大小太大)或导致内存损坏(如果块大小太小)。

在您的代码中,在semaphoreCreateBinary()函数内部

 ro_Handle = Semaphorehandle1;

不会达到您的目的。 指针ro_Handle 本身通过传递值传递给函数,因此您不能从函数更改指针本身,并且不能期望它反映函数外部的更改。 您可以更改指针所指向的值,它将保持不变,但不能持续。

如果要更改指针,则需要传递指针的地址作为指针到指针。

话说回来,

semaS *Semaphorehandle1;
Semaphorehandle1->smValue = i_InitialValue;

完全错误,因为此时Semaphorehandle1尚未初始化(即,未指向任何有效的内存位置),并且尝试取消引用未初始化的指针将导致未定义的行为 ,从而导致分段错误。 您需要先分配适当的内存,然后才能继续操作并取消引用该指针。

在您的代码中ro_Handle = Semaphorehandle1; 不会更改main范围中指针的值,因为该指针是semaphoreCreateBinary范围中的副本(按值传递)。 为了编辑指针的值,您需要一个指向它的指针:

unsigned int semaphoreCreateBinary(void **ro_Handle,unsigned int i_InitialValue) {
    ...
    *ro_Handle = Semaphorehandle1;

然后,您需要将指针的地址传递给该函数:

semaphoreCreateBinary(&s1vPtr,0);

似乎您对指针的工作方式有一些严重的误解。 指针是一个变量, 可以存储有效变量的位置 ,但不必存储-这取决于您是否正确初始化了指针。 你的线

semaS *Semaphorehandle1;

声明一个未初始化的指针,即指向任意内存位置的指针。 下一行

Semaphorehandle1->smValue = i_InitialValue;

然后取消引用未初始化的指针,从而写入任意的内存位置-这是典型的内存损坏,可能会导致整个程序出现未定义的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM