void指向结构指针的指针

时间:2015-12-15 20:20:52

标签: c pointers struct pass-by-reference pass-by-value

我有一个将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,否则我会改变它。

5 个答案:

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

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

  1. 在C中,如果你想要一个函数来修改某些东西,你必须传递一个指向那个东西的指针。在您的情况下,您想要修改semaS*指针(让它指向新malloc ed内存位置)。因此,如果您要修改semaS*,则必须将semaS**传递给该函数。
  2. 可以将void*强制转换为任何指针类型,包括指针指向指针。
  3. 另请注意,您的初始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;

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