链表中的字符串彼此重叠C

时间:2018-11-23 23:21:44

标签: c string memory linked-list

我正在尝试建立一个结构来记录一群人。由于某种原因,每当我输入此人的房间名称时,该房间名称都会替换该人的名字。这在Test 5中的addResi函数中显示。

struct resi {
    char *firstname;
    char *lastname;
    double stnscore;
    char *roomName;
    struct resi *next;
};
struct resi *head = NULL;
struct resi *current = NULL;

void printAll() {
    struct resi *outer = head;
    if (outer == NULL) {
        printf("Empty\n"); fflush(stdout);
    }
    while (outer != NULL) {
        printf("First Name: %s, Last Name: %s, Score: %lf, roomName: %s\n", outer->firstname, outer->lastname, outer->stnscore, outer->roomName); fflush(stdout);
        outer = outer->next;
    }
}
void addResi(char *firstname, char *lastname, double stnscore, char *roomName) {
    printf("test 0\n"); fflush(stdout);

    struct resi *link = (struct resi*) malloc(sizeof(struct resi));
    printf("test 1 %s\n", firstname); fflush(stdout);

    strcpy(link->firstname, firstname);
    printf("test 2 %s\n", link->firstname); fflush(stdout);

    strcpy(link->lastname, lastname);
    printf("test 3\n"); fflush(stdout);

    link->stnscore = stnscore;
    printf("test 4\n"); fflush(stdout);

    strcpy(link->roomName, roomName);
    printf("test 5 %s %s\n", link->firstname, link->roomName); fflush(stdout); //they shouldn't be the same.

    link->next = head;
    head = link;
}

int main (void)
{
    int totalStud, tempX = 0;
    char firTemp[21], lasTemp[21], roomTemp[21];
    double scrTemp;

    printf("How many residences?\n"); fflush(stdout);
    scanf("%d", &totalStud);
    if (totalStud < 5) {
        printf("The number %d is less than 5, please type a different number\n",
            totalStud); fflush(stdout);
    }
    while (totalStud < 5) {
        scanf("%d", &totalStud);
    }

    printf("type the residences with following format\nfirst name last name score room\n"); fflush(stdout);

    for (tempX = 0; tempX < totalStud; tempX++) {
        scanf("%20s %20s %lf %20s", firTemp, lasTemp, &scrTemp, roomTemp);
        printf("test mid %s %s %lf %s\n", firTemp, lasTemp, scrTemp,
            roomTemp); fflush(stdout);
        addResi(firTemp, lasTemp, scrTemp, roomTemp);
        printAll();
    }
}

如果我键入“ 5”,然后输入“ Bob Billy 45.5 Jackson”,则最后的输出应类似于“ First Name:Bob,Last Name:Billy,成绩:45.500000,roomName:Jackson”,但显示为“ First名称:杰克逊,姓氏:Billy,得分:45.500000,房间名称:杰克逊”

2 个答案:

答案 0 :(得分:1)

resi实际上并不保留名称的空间-它仅保留指向它们的指针。我所知道的最小更改是将char *firstname更改为char firstname[256],并且对char *中的其他resi字段也进行了更改。

resi中的指针保存字符在内存中的位置,而不是字符本身。 malloc时,这些位置是未指定的-它们可以是任何东西。因此,strcpy调用将字符放置在内存中的某个位置,但是我们不确定在哪里!

由于您尚未定义将这些字符放置在何处,因此我怀疑内存中的某些随机位置是重叠的,因此几次strcpy调用将数据放置在内存的同一部分中。这可能会导致您看到的行为。

答案 1 :(得分:0)

很幸运,它能做到没有崩溃的程度。该行为是不确定的,因为您将复制到内存中的名字,姓氏和房间名指向的位置,并且这些值从未设置为有意义的值。每当使用malloc分配内存时,该内存的内容实际上都是随机的,直到初始化它为止。如前所述,您可能可以使用数组定义(例如firstname [256])进行更改,但是另一种解决方案是使用strdup而不是strcpy来复制字符串。如果删除该结构实例,则需要稍后释放此内存,以避免内存泄漏。