簡體   English   中英

ANSI C在創建結構時是否必須使用malloc()?

[英]ANSI C do you have to use malloc() when creating a struct?

假設我在ANSI C中有這個struct

typedef struct _point
{
    float x;
    float y;
} Point;

這個函數來創建這個struct

Point createpoint(float x, float y)
{
    Point p;
    p.x = x;
    p.y = y;
    return p; 
}

這允許我用這個函數創建一個struct ,即:

int main()
{
    Point pointOne = createpoint(5, 6);  
    Point pointTwo = createpoint(10, 4);
    float distance = calculatedistancefunc(pointOne, pointTwo);

    /* ...other stuff */

    return 0;
}

有人告訴我這段代碼無效,因為struct在返回之前沒有在createpoint(float x, float y)函數中獲得malloc ,並且struct將被刪除。 但是,當我像這樣使用我的struct ,它似乎沒有被刪除。

所以我的問題是:我是否需要malloc這個struct ,為什么? / 為什么不?

無論你做什么都是完全正確的。 該聲明 -

return p;

在函數中返回局部變量p副本 但是如果你想要在函數中創建的同一個對象,那么你需要malloc它。 但是,您需要稍后free它。

Point createpoint(float x, float y)
{
    Point p;
    p.x = x;
    p.y = y;
    return p; 
} // p is no longer valid from this point. So, what you are returning is a copy of it.

但是 -

Point* createpoint(float x, float y)
{
    Point *p = malloc(sizeof(Point));
    p->x = x;
    p->y = y;
    return p; 
}// Now you return the object that p is pointing to.

您可以在堆棧上返回struct ,您的代碼是有效的。 如果你要返回一個指向局部變量的指針會出現問題,但這不是你正在做的事情,你正在返回一個副本,沒關系。

C99允許更好的堆棧創建結構。
鑒於以下結構

typedef struct
{
    float x;
    float y;
} Point;

您可以使用以下語句以一些C ++構造函數樣式方式初始化它:

Point p = (Point){0.4, 0.5};

因此,您可以縮短創建點或完全廢棄它:

int main()
{
    Point pointOne = (Point){5, 6};
    Point pointTwo = (Point){10, 4};
    float distance = calculatedistancefunc(pointOne, pointTwo);
    //...other stuff
    return 0;
}
Point createpoint(float x, float y)
{
    Point p;
    p.x = x;
    p.y = y;
    return p; 
} /

函數返回after ,函數中的所有局部變量都將被刪除。

1> 按引用傳遞因此,如果要返回指向此局部變量的指針,則在函數返回后,將刪除此變量,以使指針無效。

2> 傳遞值但是這里你返回的是這個局部變量的副本,所以它的安全性是因為當函數返回時局部變量是死的,但是返回值的副本將在函數返回之前存儲在函數調用的接收器變量中。

對返回結構的方法的調用將表現得好像調用者在某個地方創建一個在任何其他范圍內不可見的結構類型的臨時變量,並為被調用函數提供指向它的指針。 然后被調用的函數將數據放在請求的位置,並在它返回后,調用者將能夠從其新變量中讀取數據。 給定一個函數和調用代碼:

StructType BuildStruct(void)
{
  StructType it;
  it.this=4;
  it.that=23;
  return it;
}

StructType myStruct;
myStruct = BuildStruct();

如果不是兩個,可能至少會有一個復制操作; 聲明return it; 可能需要從本地變量拷貝it到臨時結構,並分配給myStruct可能需要從臨時位置復制myStruct 沒有情況實際上需要兩個復制操作; 有些需要一個(可以由調用者或被調用的方法執行),有些則不需要,但復制的必要性取決於調用者和被調用方法的細節。

另一種設計是:

void BuildStruct(StructType *it)
{
  it->this=4;
  it->that=23;
}

StructType myStruct;
BuildStruct(&myStruct);

這可能會產生相當於使用結構類型返回變量的最佳代碼的代碼,因為struct數據將直接放入其最終位置,而不需要任何結構復制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM