我的问题是在C编程和非C ++的上下文中! 我试图在多个函数之间传递一个指针。但是,调用者不应该进行内存分配。我尝试了一个小例子来模拟这个。可以看出,当指针指向main函数中定义的struct变量时,它就是“工作”。正如所料。这是我的函数可以在传递地址值时操纵该内存地址中的值。但是当函数调用返回并且控制传递给main时,为什么指针会重新初始化'?指针能否以某种方式反映它指向的地址?
如何做到这一点?
这就是我所拥有的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//example to pass a struct to void pointer and a void pointer to struct
//testing if memory allocation is done by callee and not caller
typedef struct mystructure{
int a;
char b;
unsigned char c[10];
}mystruct;
void func(void *var){
mystruct *s = var;
s->a = 100;
s->b = 'I';
strncpy(s->c,"test",5);
printf("In func\n");
printf("s->a = %d\n",s->a);
printf("s->b = %c\n",s->b);
printf("s->c = %s\n",s->c);
}
void voidOut(void *var){
mystruct *s = var;
printf("In voidOut\n");
printf("s->a = %d\n",s->a);
printf("s->b = %c\n",s->b);
printf("s->c = %s\n",s->c);
}
//here is void pointer is both and 'in' and 'out' parameter
void memfunc(void *var){
mystruct *s = var;
s = (mystruct *)malloc(sizeof(mystruct));
s->a = 100;
s->b = 'I';
printf("In memfunc\n");
strncpy(s->c,"test",5);
printf("s->a = %d\n",s->a);
printf("s->b = %c\n",s->b);
printf("s->c = %s\n",s->c);
}
//here is void pointer is an 'in' parameter
void memvoidOut(void *var){
mystruct *s = var;
printf("In memvoidOut\n");
printf("s->a = %d\n",s->a);
printf("s->b = %c\n",s->b);
printf("s->c = %s\n",s->c);
}
int main(int argc, char *argv[]){
mystruct val;
func(&val);
voidOut(&val);
mystruct *ptr = NULL;
memfunc(ptr);
memvoidOut(ptr);
return 0;
}
更新: 根据答案和评论,我就是这样:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//example to pass a struct to void pointer and a void pointer to struct
//testing if allocation is done by callee and not caller
typedef struct mystructure{
int a;
char b;
unsigned char c[10];
}mystruct;
void func(void *var){
mystruct *s = var;
s->a = 100;
s->b = 'I';
strncpy(s->c,"test",5);
printf("In func\n");
printf("s->a = %d\n",s->a);
printf("s->b = %c\n",s->b);
printf("s->c = %s\n",s->c);
}
void voidOut(void *var){
mystruct *s = var;
printf("In voidOut\n");
printf("s->a = %d\n",s->a);
printf("s->b = %c\n",s->b);
printf("s->c = %s\n",s->c);
}
//here is void pointer is both and 'in' and 'out' parameter
void memfunc(void **var){
mystruct *s = var;
s = (mystruct *)malloc(sizeof(mystruct));
s->a = 100;
s->b = 'I';
printf("In memfunc\n");
strncpy(s->c,"test",5);
printf("s->a = %d\n",s->a);
printf("s->b = %c\n",s->b);
printf("s->c = %s\n",s->c);
//memcpy(var,s, sizeof(s));
}
//here is void pointer is an 'in' parameter
void memvoidOut(void **var){
mystruct *s = var;
printf("In memvoidOut\n");
printf("s->a = %d\n",s->a);
printf("s->b = %c\n",s->b);
printf("s->c = %s\n",s->c);
}
int main(int argc, char *argv[]){
mystruct val;
func(&val);
voidOut(&val);
mystruct *ptr = NULL;
memfunc(&ptr);
memvoidOut(&ptr);
return 0;
}
但我的输出是:
In func
s->a = 100
s->b = I
s->c = test
In voidOut
s->a = 100
s->b = I
s->c = test
In memfunc
s->a = 100
s->b = I
s->c = test
In memvoidOut
s->a = 0
s->b = d
s->c =
我错过了什么?我在memvoidOut中为结构定义内存?
答案 0 :(得分:3)
您应该更改分配新内存的函数的签名:
void memfunc(void *var)
到
void memfunc(void **var)
并从主要
致电memfunc(&ptr)
说明:
你的memfunc函数,复制传递的指针ptr。最初,它将此指针分配给已分配的空间(通过malloc),但是,在函数返回后,指针仍然是传递给memfunc的原始指针(即NULL),因为该ptr指针的副本已被回收。 p>
现在,如果按照建议改变它,指针的地址将被传递,因此你不会面对“复制指针”问题
答案 1 :(得分:1)
函数参数由C中的值传递。因此,您无法传递指针本身并从被调用函数中将内存分配给指针本身。
你可以做两件事之一
将指针的地址从另一个函数传递给已分配的内存。
传递指针,分配内存,从函数和调用者返回分配的指针,在同一指针中收集返回值。
因此,如果是memfunc()
,则
您必须更改签名以传递&ptr
,收集mystruct **var
,然后在函数内部为*var
分配内存
您需要返回mystruct *
并在ptr
收集该内容。