声明Int变量会导致分段错误?

问题描述:

嘿家伙我在我的程序中出现了一个非常奇怪的分段错误。这个程序假设自动化纸牌游戏“战争”,到目前为止,我已经能够为两个玩家构建两个随机化的半套牌。这似乎表明排队工作正确。我也能够将所有值排队,并且它们以正确的顺序出现。但是,如果我每次取消注释主程序段错误中的整数声明,主内部。我不能为了我的生活找出简单的声明可能会导致错误。请注意,这是我使用队列的唯一第二项任务。声明Int变量会导致分段错误?

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

typedef struct node 
{ 
    int value; 
    int suit; 
    char*sname; 
    char*txt; 
    struct node *next; 
} node; 
int isempty(node *base){ 
    if (base==NULL) 
     {return 1;} 
    else 
     return 0; 
} 
void printlist(node *base){ 
    node *current=base;         
    if(base==NULL) 
     { 
      printf("The List is empty!\n"); 
      return; 
     } 
    else 
     { 
      printf("Content: \n"); 
      int count=0; 
      while(current!=NULL){ 
       count++; 
       printf("%s \tof \t%s\n",current->txt,current->sname); 
       current=current->next; 
      }              
      printf("\nCount:%d\n",count); 
     } 
    }  
char* valname(int n){          
    char *name;           
    switch(n)            
    {              
     case 0:name="two";break;       
     case 1:name="three";break;      
     case 2:name="four";break;      
     case 3:name="five";break;       
     case 4:name="six";break;       
     case 5:name="seven";break;      
     case 6:name="eight";break;      
     case 7:name="nine";break;       
     case 8:name="ten";break;       
     case 9:name="Jack";break; 
     case 10:name="Queen";break; 
     case 11:name="King";break; 
     case 12:name="Ace";break; 
     default:printf("Broken\n");exit(1);    
    }             
    return(name);           
} 
char* suitname(int n){ 
    char *name; 
    switch(n){ 
     case 0:name="Hearts";break; 
     case 1:name="Spades";break; 
     case 2:name="Clubs";break; 
     case 3:name="Diamonds";break; 
     default:printf("Broken\n");exit(1); 
    } 
    return(name); 
} 
void enqueue(node **base,int item){ 
node *nn,*current=*base; 
nn=malloc(sizeof(node)); 
    if(*base==NULL) 
    { 
     *base=nn; 
    } 
    else 
    { 
     while(current->next!=NULL){ 
      current=current->next; 
     } 
     current->next=nn; 
    } 
    nn->value=item; 
    nn->txt=valname(item%13); 
    nn->sname=suitname(item/13); 
    nn->next=NULL; 
} 
int dequeue(node **base){ 
node *current=*base,*temp; 
    if (isempty(*base)==0){ 
     int giveback=current->value; 
     if(current->next==NULL) 
     { 
      free(*base); 
      *base=NULL; 
     } 
     else 
     { 
      temp=current->next; 
      free(current); 
      *base=temp; 
     } 
     return giveback; 
    }else{return -1;} 
} 
void createdecks(node **deck1,node **deck2){ 
int i=0; 
int thenumber=0; 
int deck[52]={0}; 
for(i=0;i<26;i++){ 
     thenumber=rand()%52; 
     if(deck[thenumber]==0){ 
      //add to list 
      enqueue(deck1,thenumber); 
      deck[thenumber]=1; 
     } 
     else 
     { 
      i--; 
     } 
    } 
for(i=0;i<26;i++){ 
     thenumber=rand()%52; 
     if(deck[thenumber]==0){ 
      //add to list 
      enqueue(deck2,thenumber); 
      deck[thenumber]=1; 
     } 
     else 
     { 
      i--; 
     } 
    } 
} 
int main(void){ 
    node *d1,*d2,*warholder; 
    //int c1=0,c2=0;     //THIS LINE!!!!!!!!!!! 
    srand(time(NULL)); 
    createdecks(&d1,&d2); 
    //printlist(d1); 
    //printlist(d2); 
    int i=0; 
    for(i=0;i<26;i++) 
     printf("%d ",dequeue(&d1)); //return testing 
    printf("\n"); 
    printlist(d1); 
} 

教授的例子功能

char * namenum(int num) 
{ 
    char * name; 
    switch(num) 
    { 
     case 0: 
      name = "zero"; break; 
     case 1: 
      name = "one"; break; 
     case 2: 
      name = "two"; break; 
     case 3: 
      name = "three"; break; 
     case 4: 
      name = "four"; break; 
     case 5: 
      name = "five"; break; 
     case 6: 
      name = "six"; break; 
     case 7: 
      name = "seven"; break; 
     case 8: 
      name = "eight"; break; 
     case 9: 
      name = "nine"; break; 
     default: 
      printf("Invalid Number generated\n"); 
      exit(1); 
    } 
    return name; 
} 
+0

初始化您的三分球为主,看它是否消失。我猜想你的栈上有垃圾会导致指针在第一次插入时不是空的,尽管它们没有指向任何分配的内存。 *编辑*并声明已归零的int影响指针的初始状态,这就是为什么你的程序与它们一起运行的原因。 – 2015-03-31 19:14:09

+0

如果您有Valgrind,请尝试在此下运行它 - 它会立即在此处检测到问题。 – teppic 2015-03-31 19:43:58

+0

@Tyler请不要编辑这个问题以表达“回答”或“编辑”等问题。这让人们第一次看到这个问题时感到困惑。相反,接受张贴的答案,这就是你需要做的。 – 2015-03-31 21:10:23

我简单地看了一下代码,它看起来像你有一个未初始化变量的问题。您在main()声明如下:

node *d1,*d2,*warholder; 

然后你把它传递给createdecks(),进而调用enqueue()enqueue()假定指针已初始化。

尝试在main()初始化d1d2

node *d1,*d2,*warholder; 
d1 = d2 = warholder = NULL; 
+0

我以为我在排队功能中照顾了这一点。 – Tyler 2015-03-31 19:26:29

+2

没有@Tyler,除非你指定一个值,否则在函数中声明的变量*不*保证用值初始化。你检查基础是否为空,这是好的,但是你在最初声明的基础上(初始化为main)初始化为null。如果某些事情发生在堆栈上,base可能有一个非null值,即使你没有给它分配任何东西。 – 2015-03-31 19:29:49

+0

真棒哥们谢谢你!这一切都修好了! – Tyler 2015-03-31 19:31:48

它不是由于声明INT。在使用它之前,您还没有将内存分配给char *名称。例如

char* valname(int n){          
    char *name;  

上面的代码后使用的名字前使用malloc()分配内存

char* suitname(int n){ 
    char *name; 

一错再错

如果你想避免这种情况使用数组,而不是指针

+0

这绝对不是原因,因为如果'name'保持在每个函数的本地,那么没有什么不好的事情会发生。当它返回时,它就是问题发生的地方。 – 2015-03-31 18:49:51

+0

哦,真的吗?当没有内存时,如何将一个值赋给char *?我会生气 – 2015-03-31 18:54:45

+0

这是因为你正在分配指针,而不是它的价值。它完美无瑕!但一旦你得到它,你将成为编程的上帝。我认为你可能是穆斯林,所以我希望编程上帝不会冒犯,我的父亲也是穆斯林,我只是无法理解上帝的理论,所以我不是。函数'name'内部指向存储字符串文字的位置,并且它是有效的。该位置是该函数的堆栈框架,所以当该函数返回时,该函数将释放该函数。 – 2015-03-31 18:59:50