简体   繁体   中英

C code, compiler Xcode, detected source and destination buffer overlap

I'm doing a project for school in which I have to create a program that plays go fish. In which a deck of cards is in a doubly linked list. I read the cards from a file in the function Addcard. I have a function to print the cards and a function that is supposed to shuffle the cards. I have ot use the parameters of the struct to implement the cards. I sometimes see the error "detected source and destination buffer overlap" when I run the shuffle function, sometimes not. When the error comes up it says Thread 1: signal SIGABRT next to a string copy function. I believe it has something to do with the buffer size of some kind of allocated memory being too small, but I don't really know how to fix it. Any help would be more then appreciated. Here is an excerpt of the code I have written.

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

typedef struct card_s{
char suit[7];
int value;
struct card_s *next, *previous;
}card;

int rand_gen(int count){
    double frac;
    frac = (double)rand()/((double)RAND_MAX+1);
    return floor(count * frac); //random number in [0, count]
}



void addCard(card *p, card **hl, card **hr, FILE *inp){

card *temp; // pointer to a node_t
temp = (card *)malloc(sizeof (card)); // new node creation

       fscanf(inp, "%d", &temp->value);
fscanf(inp, "%s", temp->suit);


                    if (*hl == NULL){ // if left head is null, i.e., list is empty
                        temp->previous = NULL;
                        temp->next = NULL;
                        *hl = temp;
                        *hr = temp;
                    }
                    else if (p->next == NULL){ // if adding at the end of list
                          temp->previous = p;
                        temp->next = NULL;
                        p->next = temp;
                        *hr = temp;
                    }
                    else{     // if adding to the middle of the list
                        temp->next = p-> next;
                        temp->previous = p;
                        p->next = temp;
                        temp->next->previous = temp;
                    }
                    }

void Print(card **headl)  { //this function prints from left to right only
    card *temp;
    temp = (*headl);
    while(temp != NULL) {
        printf("|");
        printf("%d", temp->value);
        if(strcmp(temp->suit,"hea")==0) {
            printf("♥");
        }
        if(strcmp(temp->suit,"clu")==0) {
            printf("♣");
        }
        if(strcmp(temp->suit,"spa")==0) {
            printf("♠");
        }
        if(strcmp(temp->suit,"dia")==0) {
            printf("♦");
        }
        printf("|");
        //printf("%s ", temp->suit);
        temp = temp->next;
    }
}
void Print1(card **headl)  { //this function prints from left to right only
card *temp;
temp = (*headl);
while(temp != NULL) {
    for(int i = 0; i < 13; i++) {
    printf("|");
        if(temp->value == 11){
           printf("J");
        }
        else if(temp->value == 12) {
            printf("Q");
        }
        else if(temp->value == 13) {
            printf("K");
        }
        else if(temp->value == 14) {
            printf("A");
        }
        else {
            printf("%d", temp->value);
        }

    if(strcmp(temp->suit,"h")==0) {
        printf("♥");
    }
    if(strcmp(temp->suit,"c")==0) {
        printf("♣");
    }
    if(strcmp(temp->suit,"s")==0) {
        printf("♠");
    }
    if(strcmp(temp->suit,"d")==0) {
        printf("♦");
    }
    printf("|");

    //printf("%s ", temp->suit);
    temp = temp->next;
    }
    printf("\n");
}
}

void swap(card *pt, int i, int j) {

card *temp;
temp = (card *)malloc(sizeof(card));
card *temp1 = pt, *temp2 = pt;  //creates temperaries that start from the head left

for(int x = 0; x < i; x++) { //counts the number of nodes until i
    temp1 = temp1->next;
}

for(int x = 0; x < j; x++) { //counts the number of nodes until j
    temp2 = temp2->next;
}
temp->value = temp1->value;  //swaps the information not the nodes
strcpy(temp->suit,temp1->suit);
temp1->value = temp2->value;
strcpy(temp1->suit, temp2->suit);
temp2->value = temp->value;
strcpy(temp2->suit, temp->suit);

}




int main(void)  {
FILE *inp = NULL;
inp = fopen("cards.txt", "r");
srand((int)time(NULL));
card *headl = NULL, *headr = NULL;

for(int i = 0; i < 52; i++) {
    addCard(headr, &headl, &headr, inp);
}

if(inp == NULL) {
    printf("No file found");
    return -1;
}

printIntro();

printf("\n");

Print1(&headl);

printf("\n");
printf("\n");


for(int i = 0; i <= 45; i++) {  //does the swap function swap number times
        swap(headl, rand_gen(52), rand_gen(52));
       }

Print1(&headl);


return(0);
}

You have an error message saying "detected source and destination buffer overlap", near a string copy function, which copies data from a source to a destination...

Are there any instances of strcpy where the source and dest might point to the same memory?

I see these two lines:

card *temp1 = pt, *temp2 = pt;  //creates temperaries that start from the head left
//advance `temp1` `i` times, and `temp2` `j` times
... 
strcpy(temp1->suit, temp2->suit);

What happens when i and j are the same value?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM