2011-02-28 25 views
1

我不記得我讀的是哪裏,如果我將一個字符串傳遞給函數。 C字符串,常量,複合文字以及爲什麼不是,代碼本身的持續時間

 
char *string; 
string = func ("heyapple!"); 
char *func (char *string) { 
    char *p 
    p = string;

return p; } printf ("%s\n", string);

字符串指針繼續有效,因爲「heyapple!」在內存中,它在我寫的代碼中,所以它永遠不會起飛,對吧?

而關於常數像1,2.10,'a'?

和複合文字?

就像如果我這樣做:

func (1, 'a', "string");

Only the string will be all of my program execution, or the constans will be too?

For example I learned that I can take the address of string doing it

&"string";

Can I take the address of the constants literals? like 1, 2.10, 'a'?

I'm passing theses to functions arguments and it need to have static duration like strings without the word static.

Thanks a lot.

+0

其實''heyapple!\ 0'在內存中。 – 2011-02-28 18:33:32

回答

2

This doesn't make a whole lot of sense.

Values that are not pointers cannot be "freed", they are values, they can't go away.

If I do:

int c = 1; 

The variable 'c' is not a pointer, it cannot do anything else than contain an integer value, to be more specific it can't NOT contain an integer value. That's all it does, there are no alternatives.

In practice, the literals will be compiled into the generated machine-code, so that somewhere in the code resulting from the above will be something like

load r0, 1 

Or whatever the assembler for the underlying instruction set looks like. The '1' is a part of the instruction encoding, it can't go away.

2

Make sure you distinguish between values and pointers to memory. Pointers are themselves values, but a special kind of value that contains an address to memory.

With char* hello = "hello";,有兩件事情發生:

  • 字符串"hello"和空終止在內存中的某處書面
  • 名爲hello變量包含一個值,該值地址內存

隨着int i = 0;只有一件事發生了:

  • 名爲i變量值爲0

當你繞過變量函數的值總是被複制。這被稱爲通過值傳遞和工作正常的基本類型,如int,double等。指針這是棘手的,因爲只有地址被複制;您必須確保該地址的內容保持有效。

簡答:是的。 1'a'由於沾染語義和"hello"由於字符串文字分配

+0

對不起,我不明白。我想你和Apalala正在互相承包...... – drigoSkalWalker 2011-02-28 19:33:48

+0

我正在解決關於通過函數傳遞它們的問題。 Apalala一般在談論文字。 – 2011-02-28 20:04:52

1

東西一樣1'a'"heyapple!"被稱爲文字,他們獲取存儲在編譯後的代碼,並在內存中時,他們必須使用。如果它們在程序期間保持或不在內存中,取決於它們在程序中聲明的位置,它們的大小和編譯器的特性,但通常可以假設是,它們被存儲在內存中的某處,他們不要走開

請注意,根據編譯器和操作系統的不同,有可能無意或故意改變文字的值。許多系統將文字存儲在內存的只讀區域(CONST部分)中,以避免令人討厭且難以調試的事故。

對於符合存儲器字的文字,如int s和char s,它們如何存儲並不重要:在整個代碼中重複文字並讓編譯器決定如何使其可用。對於較大的文字,如字符串和結構,重複是一種不好的做法,因此應該保留參考。

請注意,如果您使用宏(#define HELLO "Hello!"),編譯器需要決定要存儲多少個文字副本,因爲宏展開就是這樣的情況,即在編譯器進行之前將其替換爲宏的擴展源代碼中的一個鏡頭。如果你想確保只有一個副本存在,那麼你必須寫一樣的東西:

#define HELLO "Hello!" 
char* hello = HELLO; 

即相當於:

char* hello = "Hello!"; 

還要注意,聲明,如:

const char* hello = "Hello!"; 

保持hello不變,但不一定是它指向的內存,因爲:

char h =(char)hello; h [3] ='n';

我不知道這種情況下,在C參考定義,但我不會依賴於它:

的char *你好=「你好!」; char * hello2 =「你好!」; //是否是相同的內存?

最好把文字看作獨一無二的,並在代碼中相應地對待它們。

如果你想修改的文字,use arrays instead of pointers一個副本,所以它保證了文字(而不是一個別名)的不同副本,每次使用時:

char hello[] = "Hello!"; 

返回到您的原始問題,文字"heyapple!"的內存將可用(將被引用),只要在運行代碼中保留引用即可。在文檔中保留整個模塊(一個可加載的庫)可能會影響整個內存的使用,但這是另一個問題(您也可以強制卸載定義文字的模塊並獲取各種奇怪的結果)。

+0

okey,我知道了,但仍然存在一些問題,然後我可以將文字傳遞給函數,並將其存儲在某個位置,無論我在哪裏,我都可以獲取這些文字?我說,我不需要使用malloc來確保它不會消失嗎? – drigoSkalWalker 2011-02-28 19:23:33

+0

@drigoSkalWalker它們將保留在內存中或某個地方(一個可加載模塊),它們可以讓它們輕鬆地進入內存,但是**必須**是對文本的引用才能訪問它。更多關於擴展的答案。 – Apalala 2011-02-28 19:55:25

0

首先,it IS in the code the I wrote, so it never will be take off, right?我的回答是肯定的。我建議你看看ELF的結構或可執行文件的運行時結構。字符串字面值存儲的位置與實現相關,在gcc中,字符串字面值存儲在.rdata段中。顧名思義,.rdata是隻讀的。在您的代碼

char *p 
    p = string; 

指針p現在指向一個只讀網段的地址,所以即使函數調用結束後,該地址仍然有效。但是,如果你嘗試指針指向返回一個局部變量則是危險的,可能會導致難以發現的錯誤:

int *func() { 
    int localVal = 100; 
    int *ptr = localVal; 
    return p; 
} 
int val = func(); 
printf ("%d\n", val); 

func執行後,由於func棧空間是由檢索c運行時,localVal存儲的內存地址將不再保證保留原始值localVal的值。在func之後,可以通過操作對其進行過濾。

回到你的問題標題

-

  1. ​​有static duration
  2. 至於「關於像常數一樣,2.10,'一個'?」 我的答案是否定的,您無法使用&1獲得整數字面值的地址。你可能會被'整數常量'這個名字搞糊塗了,但是1,2.10,'a'是不對的!他們沒有標識一個內存的地方,因此,他們沒有持續時間,一個變量包含它們的值可以有持續時間
  3. 複合文字,好吧,我不知道這一點。
相關問題