![](/img/trans.png)
[英]Should memory be allocated using Malloc for this function? Does that cause a segmentation fault?
[英]Allocating memory using malloc in a function, segmentation fault
我正在嘗試運行以下程序,在該程序中,我使用稱為reserve的函數將內存動態分配給變量。 當我運行應用程序時,由於在空指針的單獨函數中分配內存而導致分段錯誤,但是如果我要在主函數中分配內存,則不會出現此錯誤。 那我在做什么錯?
這是代碼:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct{
unsigned char state;
/* socket fd of the client */
int fd;
/* File path requested by the client */
char file_path [255];
/* Current file offset */
unsigned long int offset;
} STATE;
void reserve(int length, void *context_data ,void *buffer)
{
context_data = (char *) malloc(length);
memcpy(context_data, buffer, length);
}
int main()
{
STATE test;
int length = sizeof(STATE);
char buffer[1500];
char *ptr = buffer;
test.state = 10;
strcpy(test.file_path, "Hello How are you");
memcpy(ptr, &test, length);
ptr += length;
char *context_data;
reserve(length, context_data, buffer);
STATE *temp = (STATE *) context_data;
printf("File Path %s\n", temp->file_path);
printf("State %d\n", temp->state);
}
請注意, context_data
是按值傳遞的。 因此, reserve
的本地副本已更改,但原始副本未更改。 結果, main()
的context_data
沒有初始化。 這樣您就崩潰了。
在此代碼中:
void reserve(int length, void *context_data ,void *buffer)
{
context_data = (char *) malloc(length);
memcpy(context_data, buffer, length);
}
所述context_data
參數由值來傳遞,所以context_data
的內部reserve
和context_data
以外reserve
是不一樣的指針。 因此,當您在此函數內部本地重新分配context_data
時, main
的context_data
指針不會更新,從而導致崩潰。
要解決此問題,可以采用指向context_data
變量的指針進行更新,如下所示:
void reserve(int length, void **context_data ,void *buffer)
{
*context_data = malloc(length);
memcpy(*context_data, buffer, length);
}
reserve(length, &context_data, buffer);
或者,也可以reserve
返回更新后的指針:
void* reserve(int length,void *buffer)
{
void* context_data = (char *) malloc(length);
memcpy(context_data, buffer, length);
return context_data;
}
void* context_data = reserve(length, buffer);
希望這可以幫助!
問題是您的main()
函數沒有當前的學習分配位置的方法。 您正在將指針從main()
傳遞給reserve()
,這樣可以允許子例程修改指針指向的內容……但這不是您所需要的。 你需要有reserve()
修改其中的指針指向。
void reserve(int length, void **context_data ,void *buffer)
{
*context_data = malloc(length);
memcpy(*context_data, buffer, length);
}
// in main():
char *context_data;
reserve(length, &context_data, buffer);
通過引用傳遞,您傳遞變量的地址。 這里的變量是一個指針,因此傳遞指針的地址。
像這樣稱呼它:
reserve(length, &context_data, buffer);
並更改函數定義:
void reserve(int length, void **p_context_data ,void *buffer)
{
*p_context_data = malloc(sizeof(char)*length);
.....
您將char*
傳遞給reserve()
但應這樣傳遞char**
:
char *context_data;
reserve(length, &context_data, buffer);
然后reserve
應如下所示:
void reserve(int length, void **context_data ,void *buffer) {
*context_data = (char *) malloc(length);
memcpy(*context_data, buffer, length);
}
函數reserve()
中的變量void* context_data
是局部變量,這意味着它與函數main()
變量char* context_data
不同。 它的值不會從reserve()
傳播回main()
reserve()
。 您將context_data
的值傳遞給reserve()
(未定義的值),然后將其用作STATE* temp
,但該值仍未定義。
如果要更新main()
函數的局部變量,則必須將指針傳遞給該變量。 在您的情況下,您必須將指針傳遞給指針,即您的代碼應如下所示:
void reserve(int length, void **context_data, void *buffer)
{
*context_data = (char *) malloc(length);
memcpy(*context_data, buffer, length);
}
int main()
{
...
char* context_data;
reserve(length, &context_data, buffer);
...
}
或者,您也可以更改您的reserve()
函數並使它返回指向已分配內存的指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.