gdb调试字符串倒序

本文深入探讨了使用C语言实现字符串倒序的功能,并通过GDB调试工具定位并解决了一个常见问题。详细介绍了函数实现过程、调试步骤及结果分析。

/*hello.c(字符串倒序)*/

#include <stdlib.h>

#include <string.h>


static void my_print (char *);
static void my_print2 (char *);


main ()
{
char my_string[] = "hello world!";
my_print (my_string);
my_print2 (my_string);
}
void my_print (char *string)
{
printf ("The string is %s ", string);
}
void my_print2 (char *string)
{
char *string2;
int size, i;
size =strlen (string);
string2 = (char *) malloc (size + 1);
for (i = 0; i < size; i++)
string2[size -- i] = string[i];
string2[size+1] = '\0';  //26

printf ("The string printed backward is %s ", string2);

}

在命令行输入$ gcc -g -o hello hello.c

$./hello

执行后显示如下结果:

The string is hello wrold!

The string printed backward is  

第二行打印的并不是我们所期望的,我们所预想的应该是:The string printed backward is !dlrow olleh

肯定是因为某种原因void my_print2(char*string)没有工作

用gdb调试如下

输入:gdb hello

(gdb) run
Starting program/root/hello
The string is hello world!
The string printed backward is
Program exited with code 040


list 

list

list

gdb) break 26
gdb 将作出如下的响应:
Breakpoint 1 at 0x804857cfile hello.c, line 26. //在第26行设置断点
(gdb)

(gdb) watch string2[size - i]
gdb 将作出如下回应:
Hardware watchpoint 2string2[size - i]
经过一次循环后:
Hardware watchpoint 2string2[size - i]
Old value = 0 '00'
New value = 104 'h'
my_print2 (string=0xbffffab0 "hello world!") at hello.c25
25 for (i = 0; i < size; i++)


分析:size =12,当i=11时,表达式string2[size--i]表示第1个字符‘!’最后一个字符已经拷贝到新字符串了,再把循环执行下去已经没有值在分配给字符串string2[0],因而打印print2时没有任何输出,修正这个错误很容易,只需要把第一个字符的偏移量改为size-1 而不是size 

string2[size-1-i]=string[i];

string2[size]='\0';


<think> 我们被要求用中文回答问题,并在最后提出3-5个相关问题,且第一行必须是“§§相关问题§§”且不能换行分散。 用户的问题是:gdb调试打印字符串 我们需要先回答gdb调试打印字符串的方法,然后提出3-5个相关问题。 在GDB打印字符串,通常使用`print`命令(缩写`p`)或者`x`命令。但是字符串在C/C++中可能是以字符数组、字符指针或者C++的std::string形式存在。因此,我们需要根据不同的类型采用不同的方法。 1. 对于C风格的字符串(字符数组或字符指针): 直接使用`print`命令,例如:`p (char*)0xaddress` 或者 `p *array@len`(如果知道长度)或者直接`p string_variable`(如果变量是字符指针或数组名)。 2. 对于C++的std::string: 由于std::string内部结构复杂,直接打印可能看不到字符串内容,可以使用: p string_variable.c_str() // 打印C风格字符串 或者,如果GDB支持,可以设置Python美化打印(需要GDB 7.0以上并且加载了libstdc++的pretty printers): p string_variable 3. 使用`x/s`命令:该命令可以检查内存并解释为字符串,例如:`x/s 0xaddress`。 4. 对于长字符串,可以使用`printf`命令(GDB 7.5以上)来格式化输出,例如:`printf "%s", string_variable`。 5. 设置打印选项:`set print elements 0`可以取消打印长度限制。 下面我们给出一个示例调试会话: 假设我们有以下C程序: ```c #include <stdio.h> #include <string.h> int main() { char *str1 = "Hello, GDB!"; char str2[20]; strcpy(str2, "Another string"); // C++程序的话,可能还有std::string,但这里用C示例 return 0; } ``` 编译:gcc -g test.c -o test 在GDB中: ``` (gdb) break main (gdb) run (gdb) p str1 $1 = 0x4005c4 "Hello, GDB!" (gdb) p str2 $2 = "Another string" (gdb) x/s str2 0x7fffffffe3a0: "Another string" ``` 如果遇到字符串被截断,可以使用: ``` (gdb) set print elements 0 (gdb) p str1 ``` 对于C++的std::string,假设有: ```cpp #include <string> int main() { std::string s = "Hello, std::string!"; return 0; } ``` 在GDB中: ``` (gdb) p s $1 = "Hello, std::string!" ``` 如果看不到字符串内容,可能是没有加载pretty printers,可以手动加载: ``` (gdb) source /usr/share/gcc-<version>/python/libstdcxx/v6/printers.py (gdb) p s ``` 现在,根据以上内容,我们总结回答: --- 在GDB调试打印字符串的常用方法如下: ### 1. **C风格字符串** - **直接打印变量**:若变量为`char*`或字符数组,使用`print`命令: ```gdb (gdb) p char_ptr_var ``` - **指定内存地址打印**:用`x/s`命令查看内存中的字符串: ```gdb (gdb) x/s 0x4005c4 # 打印0x4005c4地址起的字符串 ``` - **打印部分内容**:若需截取长度,使用`@`符号: ```gdb (gdb) p *char_ptr_var@20 # 打印前20个字符 ``` ### 2. **C++ std::string** - **调用`.c_str()`方法**:换为C字符串打印: ```gdb (gdb) p str_var.c_str() ``` - **启用美化打印**(需加载libstdc++ pretty printers): ```gdb (gdb) source /path/to/libstdcxx-printers.py (gdb) p str_var ``` ### 3. **长字符串处理** - **取消长度限制**: ```gdb (gdb) set print elements 0 ``` - **格式化输出**(GDB≥7.5): ```gdb (gdb) printf "%s", char_ptr_var ``` ### 4. **动态内存字符串** 若字符串位于堆内存(如`malloc`分配),直接打印指针地址: ```gdb (gdb) p (char*)malloc_ptr ``` --- §§相关问题§§ 1. 在GDB中如何打印包含非打印字符(如换行、制表符)的字符串? 2. 调试时遇到字符串地址无效(如悬垂指针)应如何安全地检查内容? 3. 如何为自定义字符串类型(如结构体中封装的字符串)实现GDB美化打印? 4. 在GDB中能否实时修改字符串内存内容?具体步骤是什么? </think>### GDB调试打印字符串的方法 在GDB调试器中打印字符串的常用命令及示例如下: #### 1. **基础打印命令** - **`print` / `p`**:直接打印变量或表达式 ```gdb (gdb) p (char*)str_ptr # 打印指针指向的字符串 (gdb) p global_str # 打印全局字符串变量 ``` - **`x/s`**:检查内存地址处的字符串 ```gdb (gdb) x/s 0x7fffffffe320 # 打印该地址的字符串内容 > 0x7fffffffe320: "Hello, GDB!" ``` #### 2. **特殊场景处理** - **打印截断字符串**(默认只显示前200字符): ```gdb (gdb) set print elements 0 # 关闭截断 (gdb) p long_str ``` - **打印非空终止字符串**: ```gdb (gdb) p {char[10]}buffer # 强制按长度打印 > {0x41, 0x42, ...} # 显示ASCII值 ``` #### 3. **结构化输出** - **打印STL字符串**(需加载libstdc++美化器): ```gdb (gdb) p std_str._M_data() # 直接访问底层指针 (gdb) p std_str # 自动美化输出 (需配置) > "C++ String" ``` - **格式化输出**: ```gdb (gdb) printf "%s\n", str_ptr # 类C语言格式化 ``` #### 4. **调试技巧** - **观察点监控字符串修改**: ```gdb (gdb) watch -l *(char(*)[20])&buf # 监控20字节缓冲区变化 ``` - **条件断点**: ```gdb (gdb) b foo.c:20 if strcmp(str, "target")==0 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值