簡體   English   中英

是否使用strcpy

[英]To use strcpy or not

如果我有一個字符串數組

char* q[2];
q[0] = "Hello";
q[1] = "World";

我想把q[0]放在一個新的字符串數組中

char* x[2];

在x [0]中調用x,我應該使用strcpy嗎?

x[0] = q[0];

這似乎有效,但過去沒有使用strcpy引起一些問題。

我是否應該這樣做以防萬一? 有什么區別?

char* a = malloc(strlen(q[0]) + 1);
strcpy(a, q[0]);
x[0] = a;

分配工作時不分配任何額外的內存。

如果使用strcpy() ,則必須在執行復制( strlen(q[0]) + 1最少strlen(q[0]) + 1個字節)之前為x[0]分配足夠的內存,並且必須確保在適當的時間釋放它。

要清楚, strcpy()沒有“破碎”; 如果它為你造成過去的某些問題” ,那是因為你的使用錯誤,而不是strcpy()任何內在問題,你應該發布一個問題,這樣你的錯誤觀念就可以得到糾正。

字符串指針賦值字符串復制之間的語義不同,因此它取決於您要執行的操作。

x是一個指針數組。 分配:

x[0] = q[0];

q[0]指向的字符串復制到x[0]指向的內存中。 而是將x[0]的值更改為q[0]引用的字符串的地址。 所以他們都在內存中引用相同的字符串 沒有移動復制字符串數據,在這種情況下只引用字符串文字:

q[0] --> "Hello"
          ^
          |
x[0] -----

從這個意義上說, x不是你所描述的“一個新的字符串數組” ,而是一個指向相同字符串的指針數組。 所以也許不是你想要的語義行為。

如果您嘗試:

strcpy( x[0], q[0] ) ;

這將是一個語義錯誤,因為在你的片段中, x[0]沒有指向任何已定義的內存,因此q[0]引用的字符串數據將被復制到某個未定義的位置,結果不確定 - 沒有好處,即使它表面上似乎工作。

如果x[0]引用一些有效分配的空間,例如要么被聲明為數組,那么:

char x[2][128] ;

或動態分配:

x[0] = malloc( 128 ) ;

或者首先被分配到其他一些有效空間:

char a[120]
x[0] = a ;

或者通過動態地分配a在你的問題的例子。

然后strcpy( x[0], q[0] )是一個有效的操作,並將q[0]引用的字符串復制x[0]引用的空間:

q[0] --> "Hello"

x[0] --> "Hello"

在這種情況下,重要的是字符串不是指內存中的相同空間。

請注意,如果您確實需要字符串指針賦值語義(可能不太可能),並且q引用文字字符串常量 ,那么對於更安全的代碼,將數組聲明為const數據的指針是很重要的:

const char* q[2] ;
const char* x[2] ;

在任何情況下, q數組都應該在這種情況下聲明為const ,但如果你想要字符串復制語義,那么顯然x不應該是const。

通過聲明const來幫助它,任何strcpy()嘗試都會在編譯時確定性地失敗,而不是有一些未定義和錯誤的,可能是潛在的運行時行為。 因此,如果確實如此,它會強制執行預期的語義。 同樣,它會阻止您嘗試修改q[n]引用的數據,這也是未定義的行為(但通常會在現代桌面操作系統上導致運行時錯誤)。

沒有一般規則,哪一個更好。 這完全取決於您對字符串的意圖用法。

如果您不打算單獨修改內存,只需指定指針即可。

如果釋放第一個指針,您仍將在第二個指針中有一個副本。 但現在它無效。 此外,如果您通過一個指針添加或更改內容,則此更改也將通過第二個指針顯示。 這是因為您使用相同的內存。

如果您復制字符串,則您擁有獨立內容。 您可以通過第一個指針釋放或修改,並仍然通過第二個指針使用它。 當然,如果您已復制到其他位置,則還必須單獨釋放內存。

當然,簡單的任務更快。 哪一個更好取決於您的需求。

我有一個字符串數組

嗯,不太好。 q被聲明為

char* q[2];

這使得它成為兩個指向char指針的數組。 在C中,通常稱為字符串的是一個以NULL結尾的char數組。

然后,為數組的每個元素分配兩個值:

q[0] = "Hello";
q[1] = "World";

"Hello""World"都是字符串文字 這里沒有復制字符串,只有指針。

稍后在代碼中你可以重新分配每個指針,就像在

q[0] = "Bye";

但任何修改字符釋放指針的嘗試都會導致很難發現錯誤。

將它聲明為指向const char的數組會更安全,如果它們是不受影響的,那么在出錯的情況下,至少錯誤消息會提供更多信息。 例如12

如果您需要可修改的字符串並控制這些對象的生命周期,您唯一的選擇是分配足夠的內存並復制字符串。

暫無
暫無

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

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