指向结构指针的空指针
void pointer to a struct pointer
我在将 void 指针分配给另一个结构指针时遇到问题。
我的输入参数在函数 semaphoreCreateBinary 中被更改,但是当它 returns 到 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
}
关于如何更正此问题的任何建议?
编辑:
即使我将参数作为地址传递:
信号量CreateBinary(&s1vPtr,0);
这是行不通的。
我无法更改输入类型,因为我们从老师那里得到的 API-Spec 否则我会更改它。
在您的代码中,在 semaphoreCreateBinary()
函数内
ro_Handle = Semaphorehandle1;
不会达到你的目的。指针 ro_Handle
本身 通过按值传递传递给函数,因此您不能从函数更改指针本身并期望它在函数外部反映该更改.你可以改变指针指向的值,它会维持,但指针不会。
如果你想改变指针,你需要传递指针的地址,作为指针到指针。
话虽如此,
semaS *Semaphorehandle1;
Semaphorehandle1->smValue = i_InitialValue;
是完全错误的,因为此时 Semaphorehandle1
未初始化(即未指向任何有效的内存位置)并尝试取消引用未初始化的指针将导致 undefined behavior,导致分段故障。您需要先分配适当的内存,然后才能真正继续并取消引用该指针。
在 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;
}
不要忘记在使用后释放内存。
在您的代码中,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;
然后取消引用未初始化的指针,从而写入任意内存位置 - 这是典型的内存损坏,可能会导致整个程序出现未定义的行为。
这个有效:
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);
}
说明:要理解为什么这是对问题的有用解决方案,有两个重要的见解是必要的 - 作为未来的软件开发人员,您需要自己获得这些见解:
- 在 C 中,如果你想让一个函数修改某些东西,你必须传递一个指向那个东西的指针。在你的例子中,你想要修改一个
semaS*
指针(让它指向新的 malloc
ed 内存位置)。所以如果你想修改一个semaS*
,你必须传递一个semaS**
给函数
- A
void*
可以转换为任何指针类型,包括指针 到 指针。
另请注意,您的 malloc
初始尺寸有误。因为你想分配一个新的 semaS
结构,你必须 malloc
一个大小为 size(semaS)
的内存块(你 malloc
ed 一个指针大小的内存块)。不幸的是,使用任何其他块大小不会在 C 中引发编译器警告或错误。但它会浪费内存(如果块大小太大)或导致内存损坏(如果块大小太小)。
我在将 void 指针分配给另一个结构指针时遇到问题。 我的输入参数在函数 semaphoreCreateBinary 中被更改,但是当它 returns 到 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
}
关于如何更正此问题的任何建议?
编辑: 即使我将参数作为地址传递: 信号量CreateBinary(&s1vPtr,0); 这是行不通的。 我无法更改输入类型,因为我们从老师那里得到的 API-Spec 否则我会更改它。
在您的代码中,在 semaphoreCreateBinary()
函数内
ro_Handle = Semaphorehandle1;
不会达到你的目的。指针 ro_Handle
本身 通过按值传递传递给函数,因此您不能从函数更改指针本身并期望它在函数外部反映该更改.你可以改变指针指向的值,它会维持,但指针不会。
如果你想改变指针,你需要传递指针的地址,作为指针到指针。
话虽如此,
semaS *Semaphorehandle1;
Semaphorehandle1->smValue = i_InitialValue;
是完全错误的,因为此时 Semaphorehandle1
未初始化(即未指向任何有效的内存位置)并尝试取消引用未初始化的指针将导致 undefined behavior,导致分段故障。您需要先分配适当的内存,然后才能真正继续并取消引用该指针。
在 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;
}
不要忘记在使用后释放内存。
在您的代码中,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;
然后取消引用未初始化的指针,从而写入任意内存位置 - 这是典型的内存损坏,可能会导致整个程序出现未定义的行为。
这个有效:
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);
}
说明:要理解为什么这是对问题的有用解决方案,有两个重要的见解是必要的 - 作为未来的软件开发人员,您需要自己获得这些见解:
- 在 C 中,如果你想让一个函数修改某些东西,你必须传递一个指向那个东西的指针。在你的例子中,你想要修改一个
semaS*
指针(让它指向新的malloc
ed 内存位置)。所以如果你想修改一个semaS*
,你必须传递一个semaS**
给函数 - A
void*
可以转换为任何指针类型,包括指针 到 指针。
另请注意,您的 malloc
初始尺寸有误。因为你想分配一个新的 semaS
结构,你必须 malloc
一个大小为 size(semaS)
的内存块(你 malloc
ed 一个指针大小的内存块)。不幸的是,使用任何其他块大小不会在 C 中引发编译器警告或错误。但它会浪费内存(如果块大小太大)或导致内存损坏(如果块大小太小)。