A day somewhere to see a C language problem, the need to reverse the string, that is, the reverse function has a bug, when the exchange of two number of times the core dump will appear, start to see this error for the pointer error, but others have debugged the discovery of the pointer is not a problem, and then did not find the problem, Then came back with GDB debugging, the function to the key section is as follows:
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 --; }}
Get Linux and write a complete program, as follows
#include <stdio.h>
voidREVERSE_STR (Char*str) { Char*p = Null,*q = Null,tmp =0; P=str; Q=str; while(* (++q)! =' /'); q--; while(P <q) {tmp= *p; *p = *Q; *q =tmp; P++; Q--; }}intMainvoid){ Char*str ="ABCDEFG"; printf ("%s\n", str); Reverse_str (str); printf ("%s\n", str); return 0;}
Compile: Gcc-o tst.elf tst.c-g, and then run, like the bug mentioned above, the core dump exits directly, and then debug: GdB./tst.elf, hit breakpoint B 5, and then one step at a time, finally found running to *p = *q this sentence, The program has the above error, but at this time the p,q pointer is not a wild pointer, pointing to the content is also correct, here a bit stuck, and then the night to search, found that the string constant read-only property caused the modification failed here, only need to modify char *str = "ABCDEFG" to Char Str[] = "ABCDEFG", modified to find the correct, the following simple summary:
Cause of the bug:
Char *str declares a string that is located in a read-only data segment and cannot be modified, resulting in *p = *q This attempt to modify read-only data throws an error and the program exits
Workaround:
Modify the string so that it is in the stack, the code is as follows
Char " ABCDEFG ";
Debug: Modify the program as follows
#include <stdio.h>voidREVERSE_STR (Char*str) { Char*p = Null,*q = Null,tmp =0; P=str; Q=str; while(* (++q)! =' /'); q--; while(P <q) {tmp= *p; *p = *Q; *q =tmp; P++; Q--; }}intMainvoid){ Char*TST ="abcdef"; CharStr[] ="abcdef"; Reverse_str (str); printf ("%s\n", str); return 0;}
Compile: Gcc-o tst.elf tst.c-g, then disassembly: objdump-d tst.elf > Tst.dis, get the relevant part of the code as shown below,
0000000000400617<main>: 400617: -Push%RBP400618: - theE5 mov%rsp,%RBP 40061b: - theEc -Sub $0x20,%RSP 40061f: - -8bGeneva - - xxMOV%fs:0x28,%Rax400626:xx xx 400628: - the $F8 mov%rax,-0x8(%RBP) 40062c: toC0 XOR%eax,%eax 40062e: -C7 $E8Geneva - +MOVQ $0x400704,-0x18(%RBP)//char *tst = "ABCDEFG"; 400635:xx 400636: C7 $F0 A + the -MOVL $0x64636261,-0x10(%RBP)//char tst[] = "ABCDEFG";40063d: theC7 $F4 $ theMOVW $0x6665,-0xc(%RBP) Disassembly of section. Rodata:0000000000400700<_IO_stdin_used>: 400700: on xxAdd%eax, (%Rax)400702: Geneva xxAdd (%rax),%Al400704: A(Bad)400705: + the - $ the(bad) {%K5}
As a result: The program generated after the compilation, Char *str will be placed in the. Rodata segment, that is, read-only segments, and Char str[] is put into the stack (RBP is the operation of the stack), is modifiable
Finally summed up a sentence:char *str definition string read-only non-writable, char str[] definition string readable writable
C Language String Reverse