2016-01-21 43 views
1

我的問題是在C編程和NOT C++的環境中! 我想通過多個函數之間的指針。但是內存分配不應該由調用者完成。我嘗試了一個小例子來模擬這個。可以看出,當指針指向一個在main函數中定義的結構變量時,它就像預期的那樣工作。這是我的功能可以操縱該地址的值通過時,在該內存地址中的值。但是,當函數調用返回並且控制傳遞給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; 
} 

UPDATE: 繼答案和評論,這裏就是我:

#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 = 

我錯過了什麼? Shoud爲memvoidOut中的結構定義內存?

+0

爲什麼要使用空指針? –

+0

當我明確地在memfunc中執行memcpy(var,s,sizeof(s))時,它可以工作。但是我想知道真正發生了什麼 – user489152

+0

我想稍後隱藏我的結構來開發API – user489152

回答

3

你應該改變這種分配新的存儲功能的簽名:

void memfunc(void *var) 

void memfunc(void **var) 

,並從主

memfunc(&ptr) 

解釋稱:

您的memfunc函數會複製傳遞的指針ptr。最初,它將此指針指定給分配的空間(通過malloc),但在函數返回後,指針仍然是傳遞給memfunc的原始指針(即NULL),因爲ptr指針的副本已被回收。

現在,如果你改變它的提議,該指針的地址將被傳遞,因此你會不會面臨「複製指針」的問題

+0

謝謝,但我剛剛添加了一條評論: \t 當我明確地在memfunc中執行memcpy(var,s,sizeof(s))時,它可以工作 – user489152

+0

memcpy與你的函數無關。這是一個tottaly不同的方法 – sestus

+0

哦,我明白了。感謝您指出傳遞的指針是副本!這解釋了 – user489152

1

函數參數通過值C傳遞。因此,您不能傳遞指針本身並從被調用函數分配內存指針本身。

您可以執行兩件事情

  1. 傳遞指針的地址從另一個函數分配的內存。

  2. 通過指針,分配內存,從函數返回分配的指針並在調用者中收集返回值的同一指針。

所以,在memfunc()情況下,無論是

  • 您必須更改簽名傳遞&ptr,在mystruct **var收集,然後在函數內部,分配內存*var

  • 您需要退回mystruct *並收集ptr

+0

在無效的memfunc(void * var)我希望以某種方式保持var參數既是'輸入'和'輸出'參數 – user489152

+0

Sourav戈什,你能解釋第二種方法嗎?我可以將返回的結構保存在void指針本身中。請您詳細說明 – user489152

相關問題