2017-09-05 82 views
0

我已经写了一个C代码来使用交换逻辑来洗牌52张卡片。该代码生成一个介于0到53之间的随机数(省略52和53),然后将其与数组中的第i个索引交换。代码如下。segfault SEGV_ACCERR - 对象的无效权限

我的问题: 当我在调用swap()函数之前注释掉display()函数调用时,程序会抛出seg故障。但是当我取消注释并在调用swap()函数之前调用显示函数时,程序工作正常,我得到所需的输出。我不知道为什么会发生这种情况。

主要功能:

int main() 
{ 
char deck[] = {'2','3','4','5','6','7','8','9','0','A','J','K','Q'}; 
char suit[] = {'D','H','S','C'}; 

char **array,**array1; 
array = malloc(sizeof(char *)*52); 
array1= array; 

srand(time(NULL)); 

for(int i=0;i<=12;i++) 
{ 
     for(int j=0;j<=3;j++) 
     { 
       if((*array = malloc(sizeof(char)*2))!=NULL) 
       { 
         sprintf(*array,"%c%c",deck[i],suit[j]); 
         *array++; 
       } 
     } 
} 

//display(array1); // when i comment this line, the program throws segfault. when i uncomment it the program runs fine. 
swap(array1); 
display(array1); 
free_array(array1); 
return 0; 
} 

这里是其他功能的交换和显示。

void display(char **array) 
{ 
char **temp; 
temp = array; 

for(int i=0;i<=51;i++) 
{ 
     printf("temp [%s]\n",*temp); 
     *temp++; 
} 

return; 
} 

void swap(char **array) 
{ 
char **temp; 
int x; 
temp = array; 
char *temp1; 

for(int i=0;i<=51;i++) 
{ 
     x = rand()%53; 
     if(x == 53 || x == 52) 
       continue; 

     memcpy(temp1,temp[i],2); // program segfaults here. 
     memcpy(temp[i],temp[x],2); 
     memcpy(temp[x],temp1,2); 
} 
return; 
} 
+1

'temp1'is从来没有初始化,也不是'temp'。 –

+0

@MichaelWalz'temp = array;'初始化它。你对'temp1'是正确的。 – Barmar

回答

2

在交换功能 -

您使用的是带有了初始化它temp1目录。

void swap(char **array) 
{ 
    char **temp; 
    int x; 
    temp = array; 
    char temp1[ 2 ]; 

    for(int i=0;i<=51;i++) 
    { 
     x = rand()%53; 
     if(x == 53 || x == 52) 
       continue; 

     // need to multiply the indexes by 2 
     // allowing for the suit and deck 
     memcpy(temp1,temp[ i ],2); // program segfaults here. 
     memcpy(temp[ i ],temp[ x ],2); 
     memcpy(temp[ x ],temp1,2); 
    } 
} 

上面显示了temp1正确初始化。

我还没有检查过你的函数的其余部分,但是这会停止段错误。

+0

明白了。但是在调用swap()函数之前如何调用display()函数可以解决这个问题?因为我在调用swap()函数之前调用display()函数,所以我没有得到seg错误。另外,为什么编译器不会给我一个警告,说明该变量在使用之前未被初始化? – Shri

+0

@Shri:'temp1'具有未定义/随机内容。根据以前存储位置的用法,这可以是NULL,-1或诗的地址。 – Gerhardh

+0

@Shri编译期间是否启用所有警告? – Gerhardh

1

您有另一个UB以及

sprintf(*array,"%c%c",deck[i],suit[j]);

则需要3个字符不是两成的malloc:

*array = malloc(sizeof(char)*2))

+0

你的意思是空终止符'\ 0'? – Shri