我在编写该程序时遇到了分段错误
void swap(int *a,int *b){
int *temp;
*temp=*a;
*a=*b;
*b=*temp; }
但是当我分配一些内存时,没有分段错误
void swap(int *a,int *b){
int *temp;
temp = malloc(sizeof(int));
if (temp == NULL)
return;
*temp=*a;
*a=*b;
*b=*temp;
free(temp);
}
但是这背后的原因是什么?
答案 0 :(得分:3)
您的代码应为:
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
换句话说,在交换期间,您确实要保留一个整数值和一个指向整数的指针。
由于没有足够的内存来支持您拥有的temp
指针,并且该指针未初始化的事实意味着它指向某个随机位置,这很糟糕。取消引用它以将值保存在a
后,您便会遇到段错误。在此版本中,我们预留了堆栈空间来存储整数(不是指向整数的指针,而是实际的整数)。这意味着将保留内存以保留该值,因此我们可以将数据复制到其中并从中复制数据而不会出现问题(只要您不尝试读取或写入超出保留值的内容)。
顺便说一句,打开编译器的额外警告可能是一个好主意。如果您使用的是clang或gcc,强烈建议您在编译命令行中添加-Wall
和-Wextra
。而且,您应该考虑学习使用调试器,在调试器中可以单步调试并查看实际发生的情况。
答案 1 :(得分:2)
您只需要一个int
类型的临时存储位置。 easy的实现方式是声明temp
类型的int
:
void swap(int *a,int *b){
int temp;
temp=*a;
*a=*b;
*b=temp; }
您在第一个版本中所做的是使用temp
uninitialized,这是C程序可能不正确的多种方式之一。分配给*temp
会读取temp
的值,以便在其指向的位置进行写操作,但是temp
并未特别设置为任何值。任何事情都会发生。
在第二个版本中,您在使用之前设置temp
的值,甚至将其设置为存储int
的有效内存位置的地址,从而使所有工作正常:
temp = malloc(sizeof(int));
if (temp == NULL)
return;
尽管您决定以这种方式编写函数,但它可能会失败,因此它应该能够以某种方式向调用者指示何时失败。一种方法是使它返回成功代码,而不是void
:
// returns -1 for failure, 0 for success
int swap(int *a,int *b){
int *temp;
temp = malloc(sizeof(int));
if (temp == NULL)
return -1;
*temp=*a;
*a=*b;
*b=*temp;
free(temp);
return 0;
}
答案 2 :(得分:0)
分段错误表示您的程序已尝试访问不允许访问的内存区域。 上面的代码中可能会有细分的原因很多。我认为由于 调用交换功能时不使用&符号。
您应该使用swap(&arg1,&arg2);
调用交换功能。
但是在第二个代码中,您使用了动态内存分配,该动态内存分配会将内存分配到RAM中可用内存的区域。因此没有细分错误。