日常板砖之代码调试经验之谈

#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是不错的调试工具。

经验:使用指针时可能会导致指向的位置不确定,一定要注意。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值