简体   繁体   English

指向结构指针的void指针

[英]void pointer to a struct pointer

I have a problem with assigning a void pointer to another struct pointer. 将void指针分配给另一个结构指针时遇到问题。 My input parameter is changed inside the function semaphoreCreateBinary, but when it returns to main it is empty again. 我的输入参数在函数semaphoreCreateBinary中更改,但是当它返回到main时再次为空。 i must probably do some kind of casting but i cannot seem to get it to work. 我可能必须进行某种类型的转换,但似乎无法正常工作。

I will include the code i think is necessary to understand my problem: 我将包含我认为对理解我的问题所必需的代码:

From my header file. 从我的头文件。

typedef struct semaphoreStruct
{
    int               smValue;  
    tcbExtS           *smHolder;  
    int               smCeiling;  
}semaS;

typedef void * SemaphoreHandle;

In my C file 在我的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
}

Any suggestion how to correct this? 任何建议如何纠正这一点?

EDIT: Even if i pass the argument as an adress with: semaphoreCreateBinary(&s1vPtr,0); 编辑:即使我通过以下地址作为参数传递:semaphoreCreateBinary(&s1vPtr,0); It does not work. 这是行不通的。 I cannot change the input type since we got it from our teacher as an API-Spec otherwise i would have changed it. 我不能更改输入类型,因为我们是从老师那里获得的API规范,否则我会更改它。

In C, arguments are passed to functions by value. 在C语言中,参数按值传递给函数。 So, you change only value inside a function. 因此,您只能在函数内部更改值。 Also, there is another mistake: you don't allocate Semaphorehandle1 . 另外,还有另一个错误:您没有分配Semaphorehandle1 So, there will be segfault. 因此,将出现段错误。 This will be correct: 这将是正确的:

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

Don't forget to free memory after usage. 使用后不要忘记释放内存。

This works: 这有效:

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

Explanation: there are two important insights necessary to understand why this is a useful solution to the question - and as a future software developer you will required to gain those insights yourself: 说明:要理解为什么这是一个有用的解决方案的方法,有两个重要的见解是必要的-作为未来的软件开发人员,您将需要自己获得这些见解:

  1. In C, if you want a function to modify something, you have to pass a pointer to that something. 在C语言中,如果您希望函数修改某些内容,则必须传递一个指向该内容的指针。 In your case, you want to modify a semaS* pointer (letting it point to the newly malloc ed memory location). 在你的情况,你要修改semaS*指针(让它指向新malloc版内存位置)。 So if you want to modify a semaS* , you have to pass a semaS** to the function. 因此,如果要修改semaS* ,则必须将semaS**传递给函数。
  2. A void* can be cast to any pointer type, including a pointer to a pointer. void*可以转换为任何指针类型,包括一个指针的指针。

Also note that your initial malloc size was wrong. 还要注意,您的初始malloc大小是错误的。 Since you want to allocate a new semaS struct, you have to malloc a memory block of size size(semaS) (you malloc ed a memory block the size of a pointer). 由于要分配一个新的semaS结构,你要malloc大小的内存块size(semaS)malloc编一个内存块的指针的大小)。 Unfortunately, using any other block size will throw no compiler warnings or errors in C. But it will either waste memory (if the block size is too big) or lead to memory corruption (if the block size is too small). 不幸的是,使用任何其他块大小都不会在C中引发编译器警告或错误。但是,这将浪费内存(如果块大小太大)或导致内存损坏(如果块大小太小)。

In your code, inside the semaphoreCreateBinary() function 在您的代码中,在semaphoreCreateBinary()函数内部

 ro_Handle = Semaphorehandle1;

will not serve your purpose. 不会达到您的目的。 The pointer ro_Handle itself is passed to the function through pass-by-value, so you cannot change the pointer itself from the function and expect it to reflect that change outside the function. 指针ro_Handle 本身通过传递值传递给函数,因此您不能从函数更改指针本身,并且不能期望它反映函数外部的更改。 You can change the value pointed by the pointer, it will sustain, but not the pointer. 您可以更改指针所指向的值,它将保持不变,但不能持续。

In case you want to change the pointer, you need to pass the address of the pointer, as a pointer-to-pointer. 如果要更改指针,则需要传递指针的地址作为指针到指针。

Having said that, 话说回来,

semaS *Semaphorehandle1;
Semaphorehandle1->smValue = i_InitialValue;

is pure wrong, as at this point, Semaphorehandle1 is not initialized (ie, not pointing to any valid memory location) and attempt to dereference an uninitialized pointer will lead to undefined behavior , causing segmentation fault. 完全错误,因为此时Semaphorehandle1尚未初始化(即,未指向任何有效的内存位置),并且尝试取消引用未初始化的指针将导致未定义的行为 ,从而导致分段错误。 You need to allocate proper memory before you can actually go ahead and dereference that pointer. 您需要先分配适当的内存,然后才能继续操作并取消引用该指针。

In your code ro_Handle = Semaphorehandle1; 在您的代码中ro_Handle = Semaphorehandle1; will not change the value of the pointer in the main scope, as the pointer is a copy (passed by value) in the semaphoreCreateBinary scope. 不会更改main范围中指针的值,因为该指针是semaphoreCreateBinary范围中的副本(按值传递)。 In order to edit the value of a pointer, you need a pointer to it: 为了编辑指针的值,您需要一个指向它的指针:

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

You then need to pass the address of your pointer to the function: 然后,您需要将指针的地址传递给该函数:

semaphoreCreateBinary(&s1vPtr,0);

It seems you have some serious misunderstanding about how pointers work. 似乎您对指针的工作方式有一些严重的误解。 A pointer is a variable that may store the location of a valid variable, but does not have to - this depends on whether you correctly initialize your pointer. 指针是一个变量, 可以存储有效变量的位置 ,但不必存储-这取决于您是否正确初始化了指针。 Your line 你的线

semaS *Semaphorehandle1;

declares an uninitialized pointer, ie a pointer that points to an arbitrary memory location. 声明一个未初始化的指针,即指向任意内存位置的指针。 The next line 下一行

Semaphorehandle1->smValue = i_InitialValue;

then dereferences your uninitialized pointer and thus writes to an arbitrary memory locations - this is a typical memory corruption that may lead to undefined behavior for your whole program. 然后取消引用未初始化的指针,从而写入任意的内存位置-这是典型的内存损坏,可能会导致整个程序出现未定义的行为。

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

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