在第一个函数中传递指向多个函数和内存分配的指针

时间:2016-01-21 09:44:08

标签: c pointers memory

我的问题是在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中为结构定义内存?

2 个答案:

答案 0 :(得分:3)

您应该更改分配新内存的函数的签名:

void memfunc(void *var)

void memfunc(void **var)

并从主要

致电
memfunc(&ptr)

说明:

你的memfunc函数,复制传递的指针ptr。最初,它将此指针分配给已分配的空间(通过malloc),但是,在函数返回后,指针仍然是传递给memfunc的原始指针(即NULL),因为该ptr指针的副本已被回收。 p>

现在,如果按照建议改变它,指针的地址将被传递,因此你不会面对“复制指针”问题

答案 1 :(得分:1)

函数参数由C中的值传递。因此,您无法传递指针本身并从被调用函数中将内存分配给指针本身。

你可以做两件事之一

  1. 将指针的地址从另一个函数传递给已分配的内存。

  2. 传递指针,分配内存,从函数和调用者返回分配的指针,在同一指针中收集返回值。

  3. 因此,如果是memfunc(),则

    • 您必须更改签名以传递&ptr,收集mystruct **var,然后在函数内部为*var分配内存

    • 您需要返回mystruct *并在ptr收集该内容。