【问题标题】:segmentation fault during execution执行期间的分段错误
【发布时间】:2012-10-20 03:55:57
【问题描述】:
#include<stdio.h>   
int main()  
{    
    char *arg[10],*c;  
    int count=0;  
    FILE *fp,*fq;  
    printf("Name of the file:");  
    scanf("%s",arg[1]);  
    fp=fopen(arg[1],"w");  
    printf("\t\t%s",arg[1]);  
    printf("Input the text into the file\n");  
    printf("Press Ctrl+d to the stop\n");  
    while((*c=getchar())!=EOF)  
    {  
            fwrite(c,sizeof(char),1,fp);  
            count++;  
    }  
    return 0;  
}  

【问题讨论】:

  • 家庭作业?如果是就没有问题。只需标记它,以便您获得更好的答案
  • 你至少可以自己写点东西
  • 如果您所做的只是邮政编码,您真的应该去codereview.stackexchange.com
  • 至少在你的帖子中写一些东西让我们知道你的问题是什么,而不是让我们假设你想知道它为什么会出现段错误。
  • 旁注:学习使用调试器。至少足以找出引发错误的行(对于 linux 上的 gcc,这将是 gdb program \n run \n [wait until it stops] bt \n,其他系统会有所不同,但仍然具有此功能)。那么您可能已经自己弄清楚了,并且可以向我们展示更短、更清晰的示例代码。

标签: c ansi


【解决方案1】:

改变这一行

char *arg[10],*c;

char arg[1000],c;

这一行

scanf("%s",arg[1]);  

scanf("%s",arg);  

还有这一行

while((*c=getchar())!=EOF)

while((c=getchar())!=EOF)

解释:

char *c; 不是字符。它是一个指向字符的指针。它一开始只是指向一个随机的内存位,它通常会充满随机数据——无论是最近写在那里的。

char c;一个字符。

同样的事情也适用于char *arg[10]。这是一个由十个指针组成的数组。它们指向随机存储器,里面充满了随机数据。

注意:我的更改不是最佳实践。如果有人要输入 1000 个字符或更长的文件名,您将覆盖arg 缓冲区的末尾。根据您的操作,这可能是一个安全漏洞。

【讨论】:

  • 我使用了 char *,这样 fwrite 的 1 个 arg 将有一个指针,我不想去寻找文件。我已经进行了必要的更改,例如 *arg[]to arg[1000],char *c to char c 但我开始直到出现分段错误。我的目的是反转文件的内容并将其粘贴到另一个文件上。上面的程序有点。
【解决方案2】:

char *arg[10];

你定义了一个包含 10 个指向 char 的指针的数组但你没有初始化它的元素。 arg[0], arg[1], ..., arg[9] 都会有未定义的值。

然后,您尝试在其中一个未定义的值中输入一个字符串。幸运的是,您遇到了分段错误。如果你不走运,你的程序could format your hard disk 代替。

【讨论】:

  • 我看不出有什么问题。为什么要投反对票?投票平衡:)
  • 我没有投反对票,我也不会为此投反对票,但是“你的程序可以改为格式化你的硬盘”有点过分了......
  • 尽管有聪明的链接,编译器可以生成它喜欢的所有代码,没有现代操作系统可以让它格式化高清。我坚持过度鸡蛋。
  • @Jon:以后我会尽量记住使用我的其他 UB 示例...让计算机从 USB 端口渗出柠檬汁
  • @pmg 我其实更喜欢那个。更简洁地传达了这一点:-)
【解决方案3】:
char *arg[10] ;

arg 是 char 指针数组。在输入之前,您需要使用 malloc 为它们分配内存位置 -

scanf("%s",arg[1]); // arg[1] is not assigned to point to any memory location
                    // and is what causing the segmentation fault.

也是这样-

arg[1] = malloc( stringLengthExpectedToEnter + 1 ) ; // +1 for termination character

其他数组元素也应该这样做(或)只需将 char*arg[10] 更改为 char arg[10] 并确保只输入 9 个字符。


我认为您混淆了指针普通变量

int *ptr;

ptr 是可以保存整型变量地址的变量。为ptr 变量分配内存以保存整数地址。而已。 ptr 处于未初始化状态,并且没有指向(或)可能指向垃圾的位置。取消引用未初始化指针的行为是未定义的,如果它给出了 segmentation-fault,你就足够幸运了。

现在,您需要使用 malloc 为其分配一个有效的内存位置。

ptr = malloc( sizeof(int) ) ; // Allocates number of bytes required to hold an
                              // integer and returns it's address.

所以,ptr 现在指向从可以保存整数的空闲存储中获取的内存位置。从免费存储中获取的这些位置必须使用free 释放,否则您将遇到内存泄漏的经典问题。在声明时初始化指向 NULL 的指针是一个好习惯。

int *ptr = NULL ;

希望对你有帮助!

scanf("%d", ptr) ; // Notice that & is not required before ptr. Because ptr 
                   // content is address itself.

正常变量的故事完全不同。声明时 -

int var ;

内存分配给var 以保存整数。因此,您可以直接为其分配一个整数。

【讨论】:

  • 很好的解释,但我在这里有疑问。指针的内存是静态的还是在退出程序后永久存储(如果我没有动态分配内存)以及内存存储在哪里就像在命令行中 args ex- int main(argc ,*argv[])......
【解决方案4】:
#include<stdio.h>   
int main()  
{    
   char arg[10],c;  
   int count=0;  
   FILE *fp;  
   printf("Name of the file:");  
   scanf("%s",arg);  
   fp=fopen(arg,"w");  
   printf("\t\t%s",arg);  
   printf("Input the text into the file\n");  
   printf("Press Ctrl+d to the stop\n");  
   while((c=getchar())!=EOF)  
   {  
        fwrite(&c,sizeof(char),1,fp);  
        count++;  
   }

   if(fp != NULL){
      fclose(fp);
      fp = NULL;
   }
   return 0;  
}  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-25
    • 2020-10-14
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    相关资源
    最近更新 更多