簡體   English   中英

C動態結構(malloc和free)

[英]C dynamic struct (malloc and free)

我正在嘗試學習C,C ++編程的基礎知識,所以我從“C”開始。 我有很多使用Java和VB編程的經驗。 但“C”是我想學的東西。 所以我遇到了一個問題,試圖理解“malloc”和“free”函數。

我在Windows 98上使用Borland C ++ 4.5和Visual C ++ 6.0。 - (只是一個測試環境,想學習非常基礎和早期的Windows編程)。

請參閱此代碼:

struct String
{
 char *value;
 int length;
};
char *initString(const char *value)
{
 char *str = (char*)malloc( strlen(value)+1 );
 strcpy(str, value);
 return str;
}

struct String *InitString(const char *text)
{
 struct String *str = (struct String*)malloc( sizeof(struct String) );

 str->value = initString(text);
 str->length = strlen( str->value );
 return str;
}
void freeString(struct String *str)
{
 free(str->value);
 free(str);
 str = NULL;
}
int main(int argv, char *argc[])
{
 struct String *theString = InitString("Testring string struct");

 printf("String: %s\n", theString->value);
 printf("String Length: %d\n", theString->length);

 freeString(theString);

 printf("\nData: %s", theString->value);

 return 0;
}

該程序運行時,結果是正確的。
在我調用“ freeString(theString) ”之后,該函數釋放內存並在“freeString()”函數內將結構設置為NULL,當我傳入指針時,該函數應釋放“main()”中的“theString”到“theString”,但是當函數返回時:“theString”不是“NULL”。

在Borland 4.5上,我仍然可以使用“theString-> value”調用“printf”並打印字符串。 在Visual C ++上,程序在調用“printf”時崩潰 - 但“theString”仍然不是“NULL”。 當我在調試模式下跟蹤程序時,“struct”在“freeString()”函數內被釋放,並且struct被設置為NULL,但是當函數返回時,“theString”不是NULL並且“value”是仍可用於Borland,但不能用於Visual C ++。

所以我想了解,這里發生了什么? 是否應該進行一些去引用?

先感謝您!

這是你永遠不應該在它指向的內存被釋放后使用指針的原因之一。 行為是未定義的,這正是您在這里看到的。

你正在看未定義的行為 (你在免費后使用了一個值),所以真的 - 任何事情都可能發生。 它可能會崩潰,或者它可以“正常”運行

可能發生的事情是msvc,至少在調試模式下,將特殊字節模式歸零或寫入你釋放的內存,這樣str->值指針變為無效並在你取消引用它時崩潰,而borland只是將內存釋放回內存游泳池,但沒有動搖。

你的str=NULL在函數中

void freeString(struct String *str)
{
 free(str->value);
 free(str);
 str = NULL;
}

沒有實際效果。 它只是將本地str值設置為NULL,調用者不受影響。

如果要將調用者的指針設置為NULL,則必須傳入指向該指針的指針,或者在C ++的情況下,傳遞對指針的引用。

void freeString(struct String *&str) //c++
{
 free(str->value);
 free(str);
 str = NULL;
}


void freeString(struct String **str) //c, call it as freeString(&theString);
{
 free((*str)->value);
 free(*str);
 *str = NULL;
}

C是按值調用的。 如果調用freeString(anotherFunction(theString))會被設置為NULL

如果要讓函數對該指針的引用具有副作用,則必須傳入指向指針的指針。

慣用C99只會在freeString()省略str = NULL的賦值。

實際上誰必須傳遞參數的指針而不僅僅是指針的地址

void freeString( struct String **str)
{
  ...
  *str=NULL;
}

否則你將指針str的副本設置為NULL而不是str本身...

並進入main()不要忘記測試NULL指針以避免崩潰:

if (theString!=NULL)
  printf("\nData: %s", theString->value);

您正在嘗試訪問已發布的字段。 這導致了不確定的行為。 盡管在某些編譯器上發布了該值,您仍然可以訪問該值,因為該特定字段不會被任何其他正在運行的應用程序重置。 即使在X-Code上,這也很愉快,但在Visual Studio Compiler上卻沒有。

暫無
暫無

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

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