这两个程序在C语言中有什么区别

这两个程序在C语言中有什么区别,c,function,pointers,segmentation-fault,C,Function,Pointers,Segmentation Fault,我有两个非常相似的程序,如下所示 程序A:运行时没有问题 #include <string.h> #include <stdio.h> typedef struct p_struct{ unsigned char* pulist; int length; } list_type; int get_struct(list_type* l) { memset(l->pulist, 0, 4); l->length=4; } int

我有两个非常相似的程序,如下所示

程序A:运行时没有问题

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

typedef struct p_struct{
   unsigned char* pulist;
   int length;
} list_type;

int get_struct(list_type* l)
{
   memset(l->pulist, 0, 4); 
   l->length=4;
}

int main ()
{
   list_type str;
   get_struct(&str);
}
#包括
#包括
类型定义结构p_结构{
无符号字符*脉冲;
整数长度;
}列表类型;
int get_struct(列表类型*l)
{
memset(l->pulist,0,4);
l->长度=4;
}
int main()
{
列表类型str;
获取结构(&str);
}
程序B:有一个附加的函数调用,仍在编译,但由于gcc的运行时错误“分段错误”而崩溃

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

typedef struct p_struct{
   unsigned char* pulist;
   int length;
} list_type;

int get_struct(list_type* l)
{
   memset(l->pulist, 0, 4); 
   l->length = 4;
}

int get_struct_a()
{
   list_type str;
   get_struct(&str);
}

int main ()
{
   get_struct_a();
}
#包括
#包括
类型定义结构p_结构{
无符号字符*脉冲;
整数长度;
}列表类型;
int get_struct(列表类型*l)
{
memset(l->pulist,0,4);
l->长度=4;
}
int get_struct_a()
{
列表类型str;
获取结构(&str);
}
int main()
{
get_struct_a();
}

我真的很难解决这个问题。谁能告诉我是什么导致了“分割错误”?另外,为什么程序B给出“分段错误”错误,而程序A没有

您没有为结构的
pulist
成员分配内存。因此,当您
memset
it时,您正在覆盖其他地方的其他内存。幸运的是,在第二种情况下,您覆盖的内存恰好没有给出SEGFULT,但您仍然在破坏内存。

您从未初始化任何东西,因此它指向任何地方。它在一种情况下崩溃,而在另一种情况下却没有崩溃,这纯粹是巧合

memset(l->pulist, 0, 14);
可能是什么让它崩溃了。在尝试将
l->pulist
用作指向某个内存的指针之前,您没有为其分配任何内存

这个

应该也会崩溃,但这是偶然的

发生的情况是,您正在堆栈上分配一个
struct
s,并且所有成员都有一些随机垃圾值(该值恰好位于分配给它的内存中)。然后,您尝试使用这些随机值中的一个作为指针,并告诉
memset
,“用0覆盖此随机位置的14个字节。”您可以看到这会导致问题的原因。但是,由于指针是随机的,所以它并不总是导致问题

你需要做一些类似的事情

l->pulist = malloc(size);

在这样的操作中使用它之前,将其设置为有效指针。

我认为结构成员pulist是未初始化的指针。在使用memset之前,您需要为此成员分配一些内存。

您尚未将
pulist
成员初始化为指向任何有意义的位置;它只包含一个随机位字符串。在程序A中,该随机位字符串对应于恰好可写的内存地址。在程序B中,它不是


两个程序都同样错误。创建
list\u type
对象时,需要显式设置
pulist
成员以指向您拥有的缓冲区

当程序试图访问不允许访问的内存位置,或试图以不允许的方式访问内存位置(例如,试图写入只读位置,或覆盖操作系统的一部分)时,会发生分段错误

分段故障的几个原因可总结如下:

  • 试图执行未正确编译的程序。请注意,如果出现编译时错误,大多数编译器不会输出二进制文件

  • 缓冲区溢出
  • 使用未初始化的指针
  • 取消对空指针的引用
  • 试图访问程序不拥有的内存
  • 试图更改程序不拥有的内存(存储冲突)
  • 超过允许的堆栈大小(可能是由于失控递归或无限循环)

通常,出现分段错误的原因是:指针要么为空,指向随机内存(可能从未初始化为任何内容),要么指向已释放/解除分配/删除的内存。

偶然?我懂了。但是这个机会似乎太高了。@pepero显然不太高,因为这就是正在发生的事情。我不知道你的意思;在这两个可执行文件中,
pulist
的位置都是固定的,但在这两种情况下有所不同。一个给你一个错误,一个没有。谢谢你,维姬和其他人。一开始,我认为这是因为没有给出“指针对象”,或者没有内存分配,我希望A中也会发生同样的“Seg错误”。然而,我在A中没有看到错误,我开始怀疑自己。@pepero,
pulist
存在,但它是一个未初始化的指针,然后被传递到
memset()
。撞车总比看起来是偶然的好。至少崩溃使问题变得明显。他旧的学校,没有用,<代码> TyBuffFrasel->pulist = malloc(size);