簡體   English   中英

帶指針的std :: swap給出分段錯誤

[英]std::swap with pointer gives segmentation fault

我有一個非常簡單的程序,但這給我一個段錯誤。 我一直在努力尋找答案。 請幫忙。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>

main() {
char *database;
int ndata=4;
database="aaa4baa3bcd2aab5";
char *dummy;
dummy=(char *)malloc(16);
memcpy(dummy,database,16);
printf("%s\n",dummy);
std::swap(database,dummy);
dummy[2]='a';
}

在交換工作正常之前分配給虛擬變量。 交換后出了什么問題。 謝謝

database指向一個字符串文字,該字符串文字已放入只讀內存中,即使指針的類型為char *而不是const char* ,也無法對其進行寫入。 嚴格來說,文字是const char *類型的,應禁止對char *類型的指針進行賦值,但這是今天仍然允許的傳統隱式轉換。

swap僅交換指針本身,而不swap它們指向的指針。 因此, swap虛擬對象之后是指包含字符串文字的內存,不允許將其寫入。

也許您應該考慮使用std::string進行字符串處理,這確實允許進行簡單的分配等,因此可以按預期進行swap

我將稍微重寫一下您的代碼,而不更改其含義

char *database = "aaa4baa3bcd2aab5";
char *dummy = (char *)malloc(16);
memcpy(dummy,database,16);
printf("%s\n",dummy);
std::swap(database,dummy);
dummy[2]='a'; //here you in fact attempt to modify a string literal

在完成swap dummy點之后, database先前指向該dummy點,這是不允許修改的字符串文字的地址。

另外請注意,字符串文字包含16個字符和一個空終止符-總共17個字符,因此,一旦分配了大小為16的緩沖區並復制了文字,則結果不會以null結尾。

字符串文字是不可變的,嘗試修改字符串可能會導致運行時失敗。 即使該語言允許char*指向字符串文字,在這種情況下,您也應始終標記pointee const: const char* database = "aaa4baa3bcd2aab5";

如果這樣做,編譯器將通知您不能交換這些指針(因為現在它們的類型不兼容),從而使您免於追查所導致的運行時錯誤的麻煩。


另外,您不應該將dummy打印為字符串,因為它不是以空字符結尾的。

數據庫包含17個字符:您計算的16個字符加上最后的'\\ 0'。 您只復制前16個,因此虛擬對象不包含最后的'\\ 0'。

所以printf("%s\\n",dummy); 將讀取虛擬對象末尾之后的內容,並且可能會訪問不允許讀取的內存。

暫無
暫無

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

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