日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

strlen() Bug

發布時間:2024/8/23 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 strlen() Bug 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

C語言strlen()以NUL作為字符串結束標記,自定義一個字符串長度統計函數消除這個Bug

分享到:
QQ空間
新浪微博
騰訊微博
豆瓣
人人網
我們知道,字符串長度統計函數 strlen() 以NUL作為字符串結束標記,但是很不幸的是,有時候字符串并不以NUL結束,例如: 復制純文本復制
  • char strA[5] = {'1', '2', '3', '4', '5'};
  • char strA[5] = {'1', '2', '3', '4', '5'}; 這個時候使用 strlen() 函數會出現莫名其妙的結果,因為 strlen() 會一直統計內存中的字符,直到遇到NUL,而什么時候遇到是不可預知的。

    請大家編寫一個安全的字符串長度統計函數,即使字符串未以NUL結尾,也不會出錯。

    注意:你需要向自定義函數傳遞一個參數,它的值就是字符串緩沖區的長度。 復制純文本復制
  • #include <stdio.h>
  • #include <string.h>
  • #include <stddef.h>
  • ?
  • /**
  • * @function 安全的字符串長度函數
  • *
  • * @param string 要計算長度的字符串
  • * @param size 字符串緩沖區長度
  • **/
  • size_t my_strlen( char const *string, size_t size ){
  • register size_t length;
  • ?
  • // 統計范圍不超過 size
  • for ( length = 0; length < size; length++ )
  • if( *string++ == '\0')
  • break;
  • ?
  • return length;
  • }
  • ?
  • int main(){
  • char strA[5] = {'1', '2', '3', '4', '5'},
  • strB[10] = "123456789";
  • ?
  • // 對比 strlen() 和 my_strlen() 的結果
  • printf("The length of strA is %d -- By strlen()\n", strlen(strA) );
  • printf("The length of strA is %d -- By my_strlen()\n", my_strlen(strA, 5) );
  • printf("The length of strB is %d -- By strlen()\n", strlen(strB) );
  • printf("The length of strB is %d -- By my_strlen()\n", my_strlen(strB, 10) );
  • ?
  • return 0;
  • }
  • #include <stdio.h> #include <string.h> #include <stddef.h>/*** @function 安全的字符串長度函數* * @param string 要計算長度的字符串* @param size 字符串緩沖區長度 **/ size_t my_strlen( char const *string, size_t size ){register size_t length;// 統計范圍不超過 sizefor ( length = 0; length < size; length++ )if( *string++ == '\0')break;return length; }int main(){char strA[5] = {'1', '2', '3', '4', '5'},strB[10] = "123456789";// 對比 strlen() 和 my_strlen() 的結果printf("The length of strA is %d -- By strlen()\n", strlen(strA) );printf("The length of strA is %d -- By my_strlen()\n", my_strlen(strA, 5) );printf("The length of strB is %d -- By strlen()\n", strlen(strB) );printf("The length of strB is %d -- By my_strlen()\n", my_strlen(strB, 10) );return 0; } 運行結果: The length of strA is 17 -- By strlen() The length of strA is 5 -- By my_strlen() The length of strB is 9 -- By strlen() The length of strB is 9 -- By my_strlen() 注意:17 明顯超出了字符數組范圍。

    C語言實現動態數組,克服靜態數組大小固定的缺陷

    分享到:
    QQ空間
    新浪微博
    騰訊微博
    豆瓣
    人人網
    C語言中,數組長度必須在創建數組時指定,并且只能是一個常數,不能是變量。一旦定義了一個數組,系統將為它分配一個固定大小的空間,以后不能改變,稱為靜態數組。但在編程過程中,有時我們所需的內存空間無法預先確定,對于這個問題,用靜態數組的辦法很難解決。

    動態數組是相對于靜態數組而言。靜態數組的長度是預先定義好的,在整個程序中,一旦給定大小后就無法改變。而動態數組則不然,它可以隨程序需要而重新指定大小。動態數組的內存空間是從堆(heap)上分配(即動態分配)的。是通過執行代碼而為其分配存儲空間。當程序執行到這些語句時,才為其分配。程序員自己負責釋放內存。

    那么,如何創建動態數組,按照需要設置數組大小呢?

    下面是一個創建動態數組的例子: 復制純文本復制
  • #include <stdio.h>
  • #include <stdlib.h>
  • ?
  • int main(){
  • int arrLen; // 數組長度
  • int *array; // 數組指針
  • int i; // 數組下標
  • ?
  • printf("輸入數組長度:");
  • scanf("%d", &arrLen);
  • // 動態分配內存空間,如果失敗就退出程序
  • array = (int*)malloc( arrLen*sizeof(int) );
  • if(!array){
  • printf("創建數組失敗!\n");
  • exit(1);
  • }
  • // 向內存中寫入數據
  • for(i=0; i<arrLen; i++){
  • array[i] = i+1;
  • }
  • // 循環輸出數組元素
  • for(i=0; i<arrLen; i++){
  • printf("%d ", array[i]);
  • }
  • printf("\n");
  • free(array);
  • system("pause");
  • return 0;
  • }
  • #include <stdio.h> #include <stdlib.h>int main(){int arrLen; // 數組長度int *array; // 數組指針int i; // 數組下標printf("輸入數組長度:");scanf("%d", &arrLen);// 動態分配內存空間,如果失敗就退出程序array = (int*)malloc( arrLen*sizeof(int) );if(!array){printf("創建數組失敗!\n");exit(1); }// 向內存中寫入數據for(i=0; i<arrLen; i++){array[i] = i+1;}// 循環輸出數組元素for(i=0; i<arrLen; i++){printf("%d ", array[i]);}printf("\n");free(array); system("pause");return 0; } 運行結果:
    輸入數組長度:10
    1 2 3 4 5 6 7 8 9 10
    請按任意鍵繼續. . .

    malloc()函數

    這里重點說明的是malloc()函數,這是一個非常重要和常用的函數。

    malloc() 用來動態分配指定大小的內存空間,以字節計,其原型為:
    ? ?void *malloc( size_t size );
    size_t 是一種自定義數據類型,在 stddef.h 頭文件中定義為:
    ? ?typedef unsigned int size_t; ?// 無符號整型

    malloc()返回值類型為 void *,這并不是說該函數調用后無返回值,而是返回一個內存結點的地址,該地址的類型為void(無類型或類型不確定),即一段存儲區的首址,其具體類型無法確定,只有使用時根據各個域值數據再確定。可以用強制轉換的方法將其轉換為別的類型。例如: 復制純文本復制
  • double*pd=NULL;
  • pd=(double*)malloc(10*sizeof(double));
  • double*pd=NULL; pd=(double*)malloc(10*sizeof(double)); 表示將向系統申請10個連續的double類型的存儲空間,并用指針pd指向這個連續的空間的首地址。并且用(double)對malloc()的返回類型進行轉換,以便把double類型數據的地址賦值給指針pd。

    sizeof

    上面的代碼中,array = (int*)malloc( arrLen*sizeof(int) ); 用來分配arrLen*sizeof(int)個字節的內存空間,并將返回的指針強制轉換為int。這里注意,int 類型的長度在不同平臺下可能不同,不要把int的長度指定為2或4,要用sizeof()來計算int的長度,以更好的跨平臺。

    使用內存中的數據

    上面的代碼中,我們通過下標(array[i])來引用數組元素,這個靜態數組沒有什么區別。另外還可以通過指針來引用數組元素,對上面的程序稍作修改: 復制純文本復制
  • #include <stdio.h>
  • #include <stdlib.h>
  • ?
  • int main(){
  • int arrLen; // 數組長度
  • int *array; // 數組指針
  • int *arrayCopy; // 數組指針副本
  • int i; // 數組下標
  • ?
  • printf("輸入數組長度:");
  • scanf("%d", &arrLen);
  • // 動態分配內存空間,如果失敗就退出程序
  • arrayCopy = array = (int*)malloc( arrLen*sizeof(int) );
  • if(!array){
  • printf("創建數組失敗!\n");
  • exit(1);
  • }
  • // 向內存中寫入數據
  • for(i=0; i<arrLen; i++){
  • *arrayCopy++ = i+1;
  • }
  • // 循環輸出數組元素
  • arrayCopy = array;
  • for(i=0; i<arrLen; i++){
  • printf("%d ", *arrayCopy++);
  • }
  • printf("\n");
  • free(array);
  • system("pause");
  • return 0;
  • }
  • #include <stdio.h> #include <stdlib.h>int main(){int arrLen; // 數組長度int *array; // 數組指針int *arrayCopy; // 數組指針副本 int i; // 數組下標printf("輸入數組長度:");scanf("%d", &arrLen);// 動態分配內存空間,如果失敗就退出程序arrayCopy = array = (int*)malloc( arrLen*sizeof(int) );if(!array){printf("創建數組失敗!\n");exit(1); }// 向內存中寫入數據 for(i=0; i<arrLen; i++){*arrayCopy++ = i+1;}// 循環輸出數組元素arrayCopy = array;for(i=0; i<arrLen; i++){printf("%d ", *arrayCopy++);}printf("\n");free(array); system("pause");return 0; } 可以發現,我們必須另外定義一個指針變量 arrayCopy,用來指向具體的數組元素。數組賦值完成后,要將 arrayCopy 重置到數組首地址,以便后面循環輸出。

    這里注意:free() 函數必須釋放整塊內存,不能只釋放一部分,或者釋放不存在的內存空間,否則程序會出錯。所以,要多定義一個變量 arrayCopy,不斷改變它的值,以指向不同的數組元素。這樣可以保證 array 變量的值不變,始終指向內存首地址,用于free()整塊內存。

    例如,如果改變了 array 的值,使其指向第5個數組元素,那在free(array)時只釋放掉了后半部分內存,而沒有釋放掉前半部分內存,這將引起程序錯誤。

    總結

    以上是生活随笔為你收集整理的strlen() Bug的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。