gcc编译程序段错误

---------------------------(一)-------------------------------------

编译时遇见了段错误,

很多时候新手都会发现段错误,其实都是内存分配错误引起的:

即用定义指针直接赋值的,那么char *p="aaa",其实和const char *p ="aaa";是一样的,都在常量区,处于静态存储区,是只读的,不可修改的,"aaa",是固定存放在.rdata段的。如果对该只读的进行操作,那么 系统就会提示“段错误”!

注意:上面的p是指针,在堆栈中,指向“aaa”这个固定的rdata,  *p是const类型,固定的,在.rdata只读段,即"aaa"

1.如果使用char *p="aaa";那么指针p 和aaa字符都在系统的只读段,常量区,是不能修改的,readonly

    但是如果使用char p[]="aaa",那么就可以修改,在读写段

2.上述的其实也就是静态分配和动态分配的问题,如果定义 char *p;  //p是只读的,而 char p[];就不是只读,是可读写的.

然后char *p可以用p=malloc()来申请一块动态的内存,free(p),那么p的内容也是可以修改的

,然后用strcpy(p,"aaa");来拷贝进入。

 

导致段错误的常见编程有:
1。坏指针错误。例如在指针赋值之前就用它来引用内存;或向库函数传递一个坏指针;

2。改写错误.越过数组边界写入数据,在动态分配的内存两端之外写入数据;
p=malloc(4);p[-1]=0;
3.释放引起的错误.释放同一块内存两次,或释放一块未曾使用malloc分配的内存等等.

 

看下这个帖子:http://bbs.chinaunix.net/viewthread.php?tid=975562&extra=&page=1

http://iseeu.blog.51cto.com/178863/140610

使用举例:

我定义一个结构体:

struct Test_SS{

             char username[16];                 //

              char *hostname;                     //

              struct other *baby;

}TT;

如果要初始化,那么可以

strcpy(TT->username,""); //整个初始化                          千万不能直接出现TT->username="aaa";   错误指针头                                                                                            这么能够指向一串字符串

或者TT->username[0]='\0';给第一个字符初始化               

TT->baby=NULL;空指针

---------------------------(二)-------------------------------------

如果main函数要调用另外的一个包含指针的函数,例如

int Get(char * username,char *hostname,char* address,struct aaa * bbb);

那么main函数中调用该函数,不能直接使用

Get(0,0,0,0);这种来初始化,必须要

定义在main函数中

char p1[11]={0};

char P2[11]={0};

char P3[11]={0};

struct aaa jiegou={0};

然后调用Get(p1,p2,p3,jiegou);这样才行

不然运行程序就出现"段错误"

原因,因为Get本身的指针是指向任何有效的内存段,如果直接放值,那么系统是不允许的,保护内存的,因为不知道该从哪里找值。

指针必须指向有效的指针地址变量.

---------------------------(三)-------------------------------------

关于字符类的函数,strcpy...strncpy..strcat..以及memset..memcpy等引起的段错误:

例如main中定义一个指针,

        char *p;     然后如果使用strcpy(p,"aaaaa");

或是char pointer[10]="goodday";

       memcpy(p,pointer,sizeof pointer);来初始化它,都会引起段错误

 

原因是因为char *p..只是定义了一个空指针p,该指针指向所有有效的内存,是一个临时的不确定的地址,如果有内存保护机制的系统,编译没有问题,但是如linux下就会提示.运行“段错误”。

所以最好养成的习惯是:

1.。。经常使用的字符串用char p[];来定义,因为这个定义下的p是一个固定的门牌号。

2.。。而结构体的定义,也是一样,定义个固定的.......例如struct aaaa bbbbb;然后调用函数的时候,使用&bbbb来传送。

3.要使用到的结构体最好都先定义一下.,不然很容易出现段错误。但是千万不要用空指针类型来定义,

     如,struct *p;之类的
<think>好的,我现在需要帮助用户解决GCC 7.5.0编译时出现的段错误问题。首先,我要仔细分析用户提供的引用资料,看看有没有相关的线索。用户提到了几个引用,其中引用[1]到[5]都是关于GCC编译过程中出现的不同错误,需要从中提取有用的信息。 首先,段错误(Segmentation Fault)通常是由于内存访问违规引起的,比如访问了未分配的内存或者已经释放的内存。在编译GCC时出现段错误,可能的原因包括内存不足、编译器本身的bug、硬件问题,或者依赖库的问题。 查看用户提供的引用,引用[1]提到了sanitizer_stoptheworld_linux_libcdep.cc中的错误,这可能是与某些系统库不兼容有关。引用[2]提到编译OpenCV时出现内部编译器错误,程序cc1plus被杀死,这可能与内存不足有关,系统杀死了编译进程。引用[3]是关于NVIDIA驱动安装时C编译器无法创建目标文件的问题,可能与编译器配置有关。引用[4]是编译GCC时的配置错误,可能缺少依赖库。引用[5]讨论的是动态链接库的问题,但用户的问题是关于编译时的段错误,可能关联不大。 接下来,我需要结合这些信息,提出可能的解决方案。首先,内存不足是一个常见原因,特别是在编译大型项目时,GCC本身需要较多内存。用户提到的引用[2]中的错误就是由于内存不足导致进程被杀死,所以建议检查内存和交换空间,或者使用并行编译减少内存占用。 其次,可能是GCC本身的bug。引用[1]中提到的Bug 81066可能与特定版本的GCC有关,虽然用户的问题是关于GCC 7.5.0的段错误,但可能需要查看是否有已知的相关bug。建议用户检查GCC的bug跟踪系统,或者尝试升级到更新的版本。 另外,硬件问题如内存故障也可能导致段错误,尤其是在编译过程中。建议用户运行内存测试工具,如memtest86+,排除硬件问题。 依赖库的问题也可能导致编译错误,比如引用了不兼容的库版本。用户需要确认所有依赖库已正确安装,并且版本符合要求。引用[4]中的配置错误可能与缺少依赖库有关,所以需要检查配置步骤是否正确,是否安装了必要的开发包。 最后,清理编译环境也是一个重要步骤,确保没有残留的旧文件干扰新编译过程。重新配置和编译,使用更严格的编译选项如CFLAGS="-O0 -g"可能帮助定位问题。 总结可能的解决方案步骤:检查内存、降级或升级GCC版本、检查硬件问题、验证依赖库、清理环境重新编译。需要将这些步骤组织成用户容易理解的建议,并引用相关的参考资料。</think>针对GCC 7.5.0编译时出现的段错误(Segmentation Fault),以下是分步骤解决方案: --- ### **1. 检查系统资源** 段错误可能由内存不足或交换空间耗尽导致。 - **查看内存状态**:通过`free -h`命令确认可用内存和交换分区大小。 - **增加交换空间**:若物理内存不足,可通过`sudo fallocate -l 4G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile`临时增加4GB交换文件[^2]。 - **减少并行编译线程**:编译时使用`make -j2`(而非`make -j$(nproc)`)降低内存占用。 --- ### **2. 排查GCC版本兼容性** 已知某些GCC版本存在编译链兼容性问题: - **降级到稳定版本**:尝试使用Ubuntu官方仓库的`gcc-5`或`gcc-9`版本(例如`sudo apt install gcc-5 g++-5`)[^1]。 - **升级到新版本**:若需保留GCC 7.5.0,可尝试升级至更高版本(如GCC 8或9)修复潜在bug。 --- ### **3. 检查硬件稳定性** 内存或CPU异常可能引发段错误: - **运行内存测试**:通过`memtest86+`工具检测物理内存是否存在故障。 - **监控编译过程**:使用`top`或`htop`观察CPU和内存使用情况,排除硬件过热或超频问题。 --- ### **4. 验证依赖库完整性** 缺少依赖或库版本冲突会导致编译异常: - **安装必要依赖**:确保已安装`build-essential`、`libc6-dev`、`binutils`等基础包[^4]。 - **清理旧配置**:删除`build`目录并重新运行`configure`脚本,避免残留配置干扰。 ```bash rm -rf build && mkdir build && cd build ../configure --prefix=/usr/local/gcc-7.5.0 --disable-multilib ``` --- ### **5. 调试编译过程** 启用调试信息定位具体错误位置: - **编译时添加调试选项**: ```bash CFLAGS="-O0 -g" CXXFLAGS="-O0 -g" make ``` - **使用GDB追踪段错误**: ```bash gdb --args gcc -c your_source.c (gdb) run ``` 观察报错时的堆栈信息,确定是否涉及特定代码文件(如`sanitizer`模块)[^1]。 --- ### **6. 参考已知解决方案** - **应用补丁修复**:若错误与特定模块(如`libsanitizer`)相关,可从GNU官方仓库下载对应补丁。 - **静态链接库**:若动态链接库存在问题,尝试静态编译(如添加`-static`选项)[^5]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值