一个奇怪的Crash【Segment Fault】问题

今天在运行程序时,遇到一个问题,偶尔程序会出问题,而且出问题时,结构体里的指针都是很奇怪的地址,而且整形变量也是奇怪的负值,如下:

(gdb) p value
$1 = {lval = -8070450165744038711, dval = -1.2883345903292424e-231, counted = 0x9000005555558cc9, str = 0x9000005555558cc9, arr = 0x9000005555558cc9, obj = 0x9000005555558cc9,
  res = 0x9000005555558cc9, ref = 0x9000005555558cc9, ast = 0x9000005555558cc9, zv = 0x9000005555558cc9, ptr = 0x9000005555558cc9, ce = 0x9000005555558cc9, func = 0x9000005555558cc9,
  ww = {w1 = 1431669961, w2 = 2415919189}}

正常情况下,地址如下:

$2 = {lval = 93825000612256, dval = 4.6355709523549613e-310, counted = 0x555555d521a0 <zend_empty_array>, str = 0x555555d521a0 <zend_empty_array>,
  arr = 0x555555d521a0 <zend_empty_array>, obj = 0x555555d521a0 <zend_empty_array>, res = 0x555555d521a0 <zend_empty_array>, ref = 0x555555d521a0 <zend_empty_array>,
  ast = 0x555555d521a0 <zend_empty_array>, zv = 0x555555d521a0 <zend_empty_array>, ptr = 0x555555d521a0 <zend_empty_array>, ce = 0x555555d521a0 <zend_empty_array>,
  func = 0x555555d521a0 <zend_empty_array>, ww = {w1 = 1440031136, w2 = 21845}}

两个地址明显有区别。

是什么原因导致这种情况呢?根据猜测,可能是赋值时,复制了栈上的没有初始化的内容,于是,就写了一个简单的程序测试测试一下test.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef union _zend_value {
	char * pValue;
	unsigned int n;
	unsigned long  l; 
} zend_value;

int main(int argc, char **argv) 
{ 
	zend_value zend;
	zend_value * pzend;
	pzend = (zend_value *)malloc(sizeof(zend_value));

	return 0; 
}


	

使用命令 gcc -g test.c -o test,编译并且可执行。

使用gdb命令调试,查看变量内容如下:

可以看到指针的初始化的内容和非指针初始化的内容是不一样的,如果定义了结构的变量没有初始化,就直接使用其中的内容会到导致严重的问题。

当然,不管什么变量,为了避免出错,最好养成好的习惯,在定义之后都初始化一下,这样可以避免可能出现的奇怪的错误。 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Segmentation fault(段错误)是一种常见的程序错误,通常是由于访问了无效的内存地址或者内存越界导致的。定位Segmentation fault问题可以通过以下几个步骤来进行: 1. 编译选项:在编译程序时,可以使用一些选项来帮助定位Segmentation fault问题。例如,在gcc编译器中,可以使用"-g"选项来生成调试信息,使用"-fsanitize=address"选项来检测内存错误。 2. 调试工具:使用调试工具可以帮助我们逐步执行程序并查看变量的值,以便找到引发Segmentation fault的原因。常用的调试工具有gdb(GNU调试器)和valgrind。 - 使用gdb:可以通过在命令行中输入"gdb <可执行文件名>"来启动gdb调试器。然后可以使用"run"命令来运行程序,并在Segmentation fault发生时暂停程序的执行。使用"backtrace"命令可以查看函数调用栈,定位到引发错误的代码行。 - 使用valgrind:可以通过在命令行中输入"valgrind <可执行文件名>"来运行程序,并检测内存错误。valgrind会输出详细的错误信息,包括引发Segmentation fault的代码行。 3. 代码审查:仔细检查代码,特别是涉及指针操作和数组访问的地方。常见的引发Segmentation fault的原因包括: - 空指针引用:使用了一个未初始化或者已经释放的指针。 - 内存越界:访问了数组或者其他数据结构的越界位置。 - 野指针:使用了一个已经释放的指针。 - 栈溢出:函数调用过深导致栈空间不足。 以上是定位Segmentation fault问题的一般步骤和方法,希望对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值