2012-11-27 136 views
0

我有这个代码的问题。我正在使用gcc编译器,当我编译并执行此代码时,我正在收到seg错误。我只是分配两个变量,name_1作为指针,name_2作为字符串。当我试图为两个值提供字符串输入时,我正在收到seg故障。此seg错误总是与我正在使用的指针变量相关联。字符串 - 分段错误

下面我提供了代码和错误的截图。

#include <stdio.h> 

int main() 
{ 
char *name_1 ; 
char name_2[10] ; 

/*  Getting 2 strings as an input from the user 
     and is stored in the pointer variable name_1 and name_2*/ 
scanf("%s",name_1) ; 
scanf("%s",name_2) ; 

/*  Printing the values of the varibales 
     name_1 and name_2 in string format  */ 
printf("\n%s",name_1) ; 
printf("\n%s",name_2) ; 

printf("\n\n") ; 
return 0 ; 
} 

请帮我看看这段代码。

Seg fault

+1

这是不是一个好主意,改变问题,以使答案已经提供无效。保留原文(也许作为评论)并显示更正是可以的;只是纠正代码并使您得到的答案无效才行。 –

+2

请注意,如果您使用的是GCC并且使用'-Wall'编译,那么您会收到编译器发出的有关您的错误的警告。如果你使用的是GCC,确保你使用(至少)'-Wall'进行编译。如果您使用其他编译器,那么了解如何打开更多警告。 –

+0

先生, 现在我实际上有更多的疑惑。每当我声明一个变量,它是不是分配一个空间? –

回答

0
char *name_1 ; 
... 
scanf("%s",&name_1) ; 

name_1是一个悬摆指针,你要使用它,这是不正确。

+0

它是一个悬挂指针还是一个未初始化的指针?不是悬挂的指针,它曾经是有效的,但不再有效(指向已退出的函数中的局部变量,或指向已被释放的动态分配内存)? –

+0

我认为在这种情况下更准确的名称是[野指针](http://en.wikipedia.org/wiki/Dangling_pointer#Cause_of_wild_pointers),尽管人们似乎在这种情况下使用了悬挂指针这个词,即使它不是严格准确。 –

3

char *name_1;,是一个指针。最初,它指向一些随机垃圾。然后,您要求scanf将随机垃圾地址name_1恰好指向程序启动时的字符串;这是未定义的行为。一致的C实现可以让这个程序按预期的方式工作,如果需要的话,只在星期二。 :)

如果你要传递一个指针,你必须确保它首先指向一个有效的缓冲区。

此外,您在呼叫scanf - name_1已经是一个指针时有间接违反的程度。您不想将指针传递给指向scanf的指针;只是一个指针。

+0

所以。如果name_1指针最初指向NULL,然后在scanf中使用,这会工作吗? –

+0

@Rajan:编号'scanf'永远不会为你分配缓冲区。这是'scanf'在生产代码中永远不能安全使用的原因之一;因为分配正确大小的缓冲区是不可能的。 –

+0

否;如果'char * name_1 = NULL;'会传递给'scanf()',它会崩溃。 –

2

问题的原始版本包含:

char *name_1; 
... 
scanf("%s", &name_1); 

的问题已经被修改为包含:

char *name_1; 
... 
scanf("%s", name_1); 

您还没有分配的任何空间name_1指向。您还通过了char **(即&name_1)至scanf(),其格式为%s,预计该格式为char *

可能的解决办法:

int main(void) 
{ 
    char name_1[20]; 
    char name_2[10]; 

    scanf("%s", name_1); 
    scanf("%s", name_2); 

另一种可能的解决办法:

int main(void) 
{ 
    char name_0[20]; 
    char *name_1 = name_0; 
    char name_2[20]; 

    scanf("%s", name_1); 
    scanf("%s", name_2); 
+0

先生, 这样做有什么用?我要指出的是,一个数组是一个更好的主意。但是我为数组变量写了另外20个字节,或者为指针变量浪费了8个字节。 –

+0

您必须设置'name_1',以便指向某个有效的地方以确保您的程序不会崩溃(或至少减少崩溃的几率 - 您需要将'%s'格式修改为'%19s'或' %9s'相当安全)。你必须有'scanf()'空间来存储它读取的数据。如果这是一个兆字节的空间,你会有理由持怀疑态度。很少有8个字节或20个字节有所不同的机器。你不是在浪费空间(尽管第二个代码片段肯定会使用更多);你正在使用它。我会选择第一个选项,但这取决于以后如何使用name_1。 –

0

你的指针char *name_1应该指向的东西。 作为一项规则遵循

Declaring a pointer variable does not create the type of variable, 
it points at. It creates a pointer variable. So in case you are pointing 
to a string buffer you need to specify the character array and a buffer 
pointer and point to the address of the character array. 

推荐变化:

  • 你可以有你char *name_1指向字符的另一个阵列或

  • 你可以把它作为一个数组..

+0

非常感谢先生。我对此感到困惑很多,现在我很好。所以我永远无法这样做。只有通过分配空间,我才能使用代码。 –

+0

通过给数组分配空间?我认为你面临的问题是理解指针。我建议你阅读[this](http://pdos.csail.mit.edu/6.828/2012/readings/pointers.pdf) – Shash

+0

谢谢先生。我正在使用指针面临麻烦。我通常使用数组而不是指针。 –