#include <stdio.h> #include <string.h> #include <stdlib.h> void upcase(char *inputstring, char **newstring); int main(void) { char *string = NULL; upcase("Hello", &string); printf("str1 = %s\n", string); upcase("Goodbye", &string); printf("str2 = %s\n", string); free(string); return 2; } void upcase(char *inputstring, char **newstring) { int counter; if (NULL == *newstring) { if (NULL == (*newstring = malloc(strlen(inputstring) + 1))) { printf("THE LINE IS %d.\n", __LINE__); printf("ERROR ALLOCATING MEMORY!\n"); exit(255); } } else { if (NULL == (*newstring = realloc(*newstring, sizeof(inputstring) + 1))) { printf("ERROR ALLOCATING MEMORY!\n"); exit(255); } } strcpy(*newstring, inputstring); for(counter = 0; counter<strlen(*newstring); counter++) { if(*newstring[counter] >= 97 && *newstring[counter] <= 122) *newstring[counter] -= 32; } }
这篇代码是调整动态内存大小的示例。文件为(realloc.c)
代码具体指的是realloc函数的调用。函数原型:void* realloc(void *ptr, size_t size);
realloc函数的作用是重新调整一块动态内存区域的大小,参数ptr是指向要调整的动态内存的额指针。如果参数ptr为NULL,则函数realloc的作用相当于函数malloc。如果参数size为0,则函数realloc的作用相当于函数free。
但是在练习过程中出现了“Segmentation fault (core dumped)”错误。
这是这篇博客的目的。第一,使用gdb解决这个问题;第二,最终出问题的原因是什么。
因为在解决过程了收到了一篇博客的启发和引导,所以在此声明一下,http://blog.csdn.net/deutschester/article/details/6739861,感谢这篇博客的作者。
~# gcc realloc.c
~# ./a.out
执行之后
~# Segmentation fault (core dumped)
首先,楼主采用在代码中添加打印信息查找问题所在
printf("The LINE is %d, The FILE is %s.\n", __LINE__, __FILE__);
但是没有解决问题。
接着,使用gdb调试工具
~# gcc reallo.c -g
~# gdb a.outCopyright (C) 2014 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "i686-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from a.out...done.(gdb)
直接运行
(gdb) runStarting program: /mnt/hgfs/A_Windows_share/test/a.out Program received signal SIGSEGV, Segmentation fault.0x080486ac in upcase (inputstring=0x80487b0 "Hello", newstring=0xbffff09c) at 2.c:4646 if(*newstring[counter] >= 97 && *newstring[counter] <= 122)
提示我们访问非法的内存。执行backetrace(=bt)命令。查看栈信息的命令。
(gdb) bt#0 0x080486ac in upcase (inputstring=0x80487b0 "Hello", newstring=0xbffff09c) at 2.c:46#1 0x08048592 in main () at 2.c:10
切换到0号堆栈帧(stack frame 0)来看看程序在哪里崩溃的。
(gdb) frame 0#0 0x080486ac in upcase (inputstring=0x80487b0 "Hello", newstring=0xbffff09c) at 2.c:4646 if(*newstring[counter] >= 97 && *newstring[counter] <= 122)
指向了46行的代码,楼主猜测可能是“*newstring[counter]”访问内存出错。打印一下结果。
(gdb) print *newstring[counter]Cannot access memory at address 0x0(gdb) print *newstring[0]$1 = 72 'H'(gdb) print *newstring[1]$2 = 85 'U'(gdb) print *newstring[2]Cannot access memory at address 0x0
几次打印出来,结果都不稳定的。所以楼主确认是此处访问内存出错。
因为“[]”小括号的优先级比“*”指针符号的优先级要高 ,所以这句代码可能执行为“*(newstring[counter])”,newstring指针在代码中为二级指针,这样访问会造成访问内存出错。
修改为“(*newstring)[counter]”,重新编译,成功运行。
这篇练习代码给我最大的启发是在执行代码中出了错,gdb是不错的调试工具。
经验:使用指针时可能会导致指向的位置不确定,一定要注意。
日常板砖之代码调试经验之谈
最新推荐文章于 2022-08-21 22:35:23 发布