2015-07-13 67 views
0

我有個問題,關於將undeclared String傳遞給FunctionC編程 - 將未聲明的字符串傳遞給函數(內存分配)

下面的代碼編譯和工作正確(在字符串被正確打印)。我試圖理解代碼如何處理內存分配的細節(編譯器是否從「String」生成一個臨時變量,並將其傳遞給函數?)

通常我會聲明一個char數組來保存字符串,然後將其傳遞給函數 - 這在內存分配方面很有意義。

如果字符串是按照下面的程序直接傳遞的話,我特別關注是否存在有關內存泄漏的問題(例如,長時間運行的程序將大量字符串傳遞到日誌 - 每個字符串是否都創建某種新的字符串變量,其內存從不釋放等)。

代碼 - 編譯在Visual Studio 2013

#include <stdio.h> 

//Function Declaration 
int MyFunction(char *SomeString); 


int main(void) 
{ 
    MyFunction("MyString"); 
    return 0; 
} 


//Function Code 
int MyFunction(char *SomeString) { 
    printf("Passed String: %s \n", SomeString); 
    return 0; 
} 

回答

2

編譯器創建一個字符串常量,當你調用MyFunction("MyString")的指針,該字符串是傳遞給函數。只要程序運行,"Mystring"字符串就會存在。

此:

MyFunction("MyString"); 

static char *mystring = "MyString"; 
MyFunction(mystring); 
3

或多或少相當於我具有與傳遞一個undeclared StringFunction的問題。

不,你不是這裏路過的未申報字符串。在你的情況,

MyFunction("MyString"); 

"MyString"稱爲字符串文字也算是一個無名變量。通常,這是駐留在不可修改的內存上。

內存分配由編譯器自己在編譯期間處理,因此您不必爲內存分配和釋放部分而煩惱。

2

程序中沒有內存泄漏。字符串文字的類型N字符長度爲const char[N+1]+1用於NUL終止符)。實際上,你的程序有const char[9]類型的隱藏的全局對象,其中包含字符MyStringNUL。您使用文字"MyString"來引用此對象。

當傳遞給MyFunction時,將創建一個類型爲char *的臨時自動對象,該對象指向該數組中的第一個字符(這是所有數組都發生的標準轉換)。通話結束後,該臨時地點將再次銷燬。數組本身的內存不是動態分配的,因此它不能泄漏。

+0

這可能是值得一提的爲OP,每當一個數組變量是在表達式中使用它被轉換爲一個指向第一數組的元素。 – jensa

+0

先生,我確實有疑問,如果在函數fun()中聲明瞭'char * c =「Some string」'。那麼'''一些字符串''仍然是* hiddden全局對象*,並且將被存儲在*初始化的只讀數據段*或將* auto *並存儲在* stack *中? – Raman

+0

@ARBY其中*正確*結束分配和存儲(物理)取決於編譯器及其優化。但是從語言的角度來看,它是一個具有靜態存儲持續時間的'const char'數組,因此是全局的。 – Angew

0

函數參數被視爲相應函數參數的初始值設定項。你可以想像這個函數調用

MyFunction("MyString"); 

通過以下方式

int MyFunction(/*char *SomeString*/) { 
    char *SomeString = "MyString"; 
    printf("Passed String: %s \n", SomeString); 
    return 0; 
} 

的字符串字面量在函數調用中使用具有字符數組char[9]的類型,並具有靜態存儲時間。那就是當編譯器編譯程序時,它將程序中使用的每個字符串字面值作爲字符數組放置在靜態存儲器中。 在函數調用中,與字符串相對應的字符數組被隱式轉換爲指向其第一個字符的指針。即編譯器創建一個類型爲char *的臨時對象,其值等於字符串文字(靜態數組)的第一個字符的地址,並將其作爲函數的參數推送到堆棧上。 所以更精確的函數調用

MyFunction("MyString"); 

可以想像這樣

char *tmp = "MyString"; 
MyFunction(tmp); 
//... 

int MyFunction(/*char *SomeString*/) { 
    char *SomeString = tmp; 
    printf("Passed String: %s \n", SomeString); 
    return 0; 
} 
相關問題