[問題] 用memcpy 會有殘餘值怎麼辦?

看板C_and_CPP (C/C++)作者 (人生在世很愜意)時間10年前 (2016/02/02 10:06), 10年前編輯推噓2(2016)
留言18則, 8人參與, 最新討論串1/3 (看更多)
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) dev C++ 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) string.h 問題(Question): 我用 memcpy (Ptr->ListString, CharPtr, Length); 去餵資料,然後用link list 去存值,在只有兩個字元時,會多了殘餘值。 餵入的資料(Input): char StringOriginalData[100] = "Abian is son of the bitch"; 預期的正確結果(Expected Output): Abian 5 is 2 son 3 of 2 the 3 bitch 5 請按任意鍵繼續 . . . 錯誤結果(Wrong Output): Abian 5 iss 2 son 3 ofs 2 the 3 bitch 5 請按任意鍵繼續 . . . 程式碼(Code):(請善用置底文網頁, 記得排版) #include <stdio.h> #include <stdlib.h> #include <string.h> char StringOriginalData[100] = "Abian is son of the bitch"; char StringChange[10] = "are"; typedef struct _VOCABULARY_LIST { char *ListString; struct _VOCABULARY_LIST *Node; }VOCABULARY_LIST; void TearOffAndAdd (VOCABULARY_LIST *Ptr); int main (int argc, char *argv[]) { VOCABULARY_LIST *FirstVocabulary; VOCABULARY_LIST *PtrVocabulary; FirstVocabulary = (VOCABULARY_LIST *)malloc (sizeof (VOCABULARY_LIST)); PtrVocabulary = FirstVocabulary; PtrVocabulary->Node = NULL; TearOffAndAdd (PtrVocabulary); system("PAUSE"); return 0; } void TearOffAndAdd (VOCABULARY_LIST *Ptr) { char *CharPtr; VOCABULARY_LIST *NewList; int Length; CharPtr = StringOriginalData; Length = strcspn (CharPtr, " "); while (Length != 0) { Ptr->ListString = (char *)malloc (Length * sizeof(char)); memcpy (Ptr->ListString, CharPtr, Length); printf ("%s", Ptr->ListString); printf (" %d\n",Length); NewList = malloc (sizeof (VOCABULARY_LIST)); NewList->Node = NULL; Ptr->Node = NewList; Ptr = NewList; CharPtr += (Length + 1); Length = strcspn (CharPtr, " "); } } 補充說明(Supplement): 這到底怎麼回事? -- 志願役普遍垃圾不代表每個志願役都是垃圾。 苗栗人智商普遍低落,不代表每個苗栗人智商都很低。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 60.250.30.118 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1454378804.A.C9F.html

02/02 11:08, , 1F
is 2(四個字元);iss 2(五個字元;
02/02 11:08, 1F
那是我compiler 看build error的值阿! 我寫的就是因為is 是兩字元,可是我memcpy之後,就給他3字元這樣。 Ptr->ListString = (char *)malloc (Length * sizeof(char)); //我配2字元給他 memcpy (Ptr->ListString, CharPtr, Length); //挑前面兩字元複製過去 printf ("%s", Ptr->ListString); //然後印出來 printf (" %d\n",Length); //監看值有沒有取對 就是這樣,但是我娶小於兩個位元他就給我印出3個位元第三個位元還給我殘餘值 ※ 編輯: apologize (60.250.30.118), 02/02/2016 11:39:24

02/02 11:43, , 2F
有一種東西叫 "結束字元"
02/02 11:43, 2F

02/02 11:55, , 3F
我用你提供的程式碼編譯,執行結果正常耶!
02/02 11:55, 3F

02/02 12:48, , 4F
要加這種東西喔 \0
02/02 12:48, 4F

02/02 14:22, , 5F
我只是覺得跟len有關,不是殘值。怎不用strtok? 作業嗎?
02/02 14:22, 5F
不是作業,想說自己練習。printf 是我想監看值有沒有存進去而已。 單純想自己配置空間,然後看值有沒有存進去。

02/03 00:27, , 6F
memcpy只是如實的複製memory裡的值喔 不會幫你生出\0
02/03 00:27, 6F

02/03 00:27, , 7F
另一方面%s是看\0決定結束在哪 你沒有給\0它不知道到哪
02/03 00:27, 7F
原來如此。

02/03 00:28, , 8F
結束
02/03 00:28, 8F

02/03 00:28, , 9F
你可以找memcpy strcpy strncpy的code比較差異
02/03 00:28, 9F
恩,所以我改成這樣寫: Ptr->ListString = (char *)malloc ((Length + 1) * sizeof(char)); memset (Ptr->ListString, '\0', Length + 1); memcpy (Ptr->ListString, CharPtr, Length); strcat (Ptr->ListString , "\0"); printf ("%s", Ptr->ListString); printf (" %d\n",Length); 謝謝 ※ 編輯: apologize (60.250.30.118), 02/03/2016 09:46:46

02/03 09:50, , 10F
為什麼要在這裡用 strcat...
02/03 09:50, 10F

02/03 09:55, , 11F
不小心多寫出來了 =
02/03 09:55, 11F

02/03 10:12, , 12F
恭喜啦。假設如果要效能好點的linklist,應減少使用memory
02/03 10:12, 12F

02/03 10:12, , 13F
的函式。你覺得如何做呢?
02/03 10:12, 13F

02/03 13:26, , 14F
除非要copy的東東是binary,結構之類才會去用memcpy
02/03 13:26, 14F

02/03 14:17, , 15F
有差喔,我還以為沒差耶
02/03 14:17, 15F

02/03 16:57, , 16F
如果你要沒差..copy的長度=strlen()+1...這不是更煩
02/03 16:57, 16F

02/03 17:00, , 17F
啊...如果要部分的話是沒什麼差..
02/03 17:00, 17F

02/03 18:57, , 18F
memcpy 丟 strlen()+1 是做兩次功...
02/03 18:57, 18F
文章代碼(AID): #1Mi0yqoV (C_and_CPP)
文章代碼(AID): #1Mi0yqoV (C_and_CPP)