C語言字串倒序

來源:互聯網
上載者:User

標籤:abc   printf   交換   完整   分代   null   資料   部分   use   

某天在某處看到一個C語言問題,要求將字串倒序,說是倒序函數有bug,當執行交換兩個數的時候會出現core dump,開始看到這個錯誤以為指標錯誤,但是別人調試過發現指標並沒有問題,然後一下就沒找到問題所在,於是回來就用gdb調試了一下,函數到關鍵區段如下:

void reverse_array(char *arr){    char *p = NULL,*q = NULL,tmp = 0;        p = arr;    q = arr;    while( *(++q) != ‘\0‘ );q--;    while(p < q){        tmp = *p;        *p = *q;        *q = tmp;        p++;        q--;    }}

拿到linux下寫了個完整程式,如下

#include <stdio.h>

void reverse_str(char *str){ char *p = NULL,*q = NULL,tmp = 0; p = str; q = str; while( *(++q) != ‘\0‘ );q--; while(p < q){ tmp = *p; *p = *q; *q = tmp; p++; q--; }}int main(void){ char *str = "abcdefg"; printf("%s\n",str); reverse_str(str); printf("%s\n",str); return 0;}

編譯:gcc -o tst.elf tst.c -g,然後運行,跟上面提到的bug一樣,出現Core Dump直接退出,接著調試:gdb ./tst.elf,打上斷點b 5,然後一次單步,最後發現運行到*p = *q這句話時,程式就出現上述錯誤了,但是此時p,q指標並不是野指標,指向的內容也都是正確的,這裡一下卡住了,然後晚上搜尋了一下,發現是字串常量的唯讀屬性導致此處修改失敗,只需要將char *str = "abcdefg" 修改為char str[] = "abcdefg",修改後發現正確了,下面簡單總結一下:

bug原因:

char *str聲明的字串位於唯讀資料區段,無法被修改,從而導致*p = *q這個嘗試修改唯讀資料引發錯誤,程式退出

解決方案:

修改字串使其處於棧區,代碼如下

char str[] = "abcdefg";

調試:修改程式如下

#include <stdio.h>void reverse_str(char *str){    char *p = NULL,*q = NULL,tmp = 0;        p = str;    q = str;    while( *(++q) != ‘\0‘ );q--;    while(p < q){        tmp = *p;        *p = *q;        *q = tmp;        p++;        q--;    }}int main(void){    char *tst = "abcdef";    char str[] = "abcdef";    reverse_str(str);    printf("%s\n",str);    return 0;}

編譯:gcc -o tst.elf tst.c -g,然後反組譯碼:objdump -D tst.elf > tst.dis,得到相關部分代碼如下所示,

0000000000400617 <main>:  400617:    55                       push   %rbp  400618:    48 89 e5                 mov    %rsp,%rbp  40061b:    48 83 ec 20              sub    $0x20,%rsp  40061f:    64 48 8b 04 25 28 00     mov    %fs:0x28,%rax  400626:    00 00   400628:    48 89 45 f8              mov    %rax,-0x8(%rbp)  40062c:    31 c0                    xor    %eax,%eax  40062e:    48 c7 45 e8 04 07 40     movq   $0x400704,-0x18(%rbp)        // char *tst = "abcdefg";  400635:    00   400636:    c7 45 f0 61 62 63 64     movl   $0x64636261,-0x10(%rbp)        // char tst[] = "abcdefg";  40063d:    66 c7 45 f4 65 66        movw   $0x6665,-0xc(%rbp)  Disassembly of section .rodata:0000000000400700 <_IO_stdin_used>:  400700:    01 00                    add    %eax,(%rax)  400702:    02 00                    add    (%rax),%al  400704:    61                       (bad)    400705:    62 63 64 65 66           (bad)  {%k5}

由此可知:編譯後產生的程式,char *str會放到.rodata段,也就是唯讀段;而char str[]則是放入棧(rbp是對棧的操作),是可修改的

最後總結起來一句話:char *str定義字串唯讀不可寫,char str[]定義字串可讀可寫

C語言字串倒序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.