【问题标题】:Lots of garbage characters in struct pointer结构指针中有很多垃圾字符
【发布时间】:2020-10-12 03:03:08
【问题描述】:

我是 C 的新手,我正在尝试制作电话簿。其中的代码是:

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

int count = 0;
struct Telephone {
    char fname[20];
    char lname[20];
    char countrycode[2];
    char areacode[3];
    char number[8];
};

void addRecord(struct Telephone *T) {
    if (count != 0) {
        struct Telephone *temp = (struct Telephone *)realloc(T, count + 1);
    }
    printf("Count: %d", count);
    printf("Enter first Name: ");
    getchar();
    do {
        gets(T[count].fname);
        T[count].fname[strlen(T[count].fname)] = '\0';
        if (strlen(T[count].fname) == 0)
            printf("Empty Value Not Permitted! Please try again: ");
    } while (strlen(T[count].fname) == 0);
    printf("Enter last name: ");
    gets(T[count].lname);
    printf("%s", T[count].lname);
    printf("Enter Country Code: ");
    gets(T[count].countrycode);
    printf("Enter Area Code: ");
    gets(T[count].areacode);
    printf("Enter Telephone Number: ");
    do {
        gets(T[count].number);
        T[count].number[strlen(T[count].number)] = '\0';
        if (strlen(T[count].number) == 0)
            printf("Value Not Permitted! Please try again: ");
    } while (strlen(T[count].number) == 0);
    count += 1;
    printf("Added\n");
}

void main() {
    struct Telephone *T = (struct Telephone *)malloc(sizeof(struct Telephone));
    int option = 1;
    while (option != 0) {
        printf("1 -> Add new record\n2 -> Search for record\n3 -> Display all record\n4 -> Update record\n0 -> Exit\nEnter: ");
        scanf("%d", &option);
        if (option == 1)
            addRecord(T);
        if (option == 3) {
            for (int i = 0; i < count; i++)
                printf("FN: %s LN: %s N: %s", T[i].fname, T[i].lname, T[i].number);
        }
    }
}

我只在开始时添加和显示方法来检查是否所有内容都正确添加。但是,当我尝试添加值时,在第一次输入后,存储的值是垃圾。我尝试添加 3 个值并打印名字、姓氏和数字。我得到的值是:

FirstName: hello LastName: └ Number: 123
FirstName: hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: Number: o1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: Number:
FirstName: ame: : hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: Number: o1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: Number:
 LastName:  LastName: : hello1 LastName: Number: o1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: Number:
 LastName:  LastName: : hello1  Number: ame: Number: o1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: Number:
 LastName:  LastName: : hello1 LastName: Number: o1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: : hello1 LastName: Number:
 LastName:  LastName: : hello1  Number:

作为参考,输入为:1-&gt;hello,world,123 2-&gt; hello1,world1,456 3-&gt;hello2,world2,789 为什么要打印此垃圾值以及如何修复它。我在这里使用了动态分配的结构指针。

【问题讨论】:

标签: c pointers struct malloc dynamic-memory-allocation


【解决方案1】:

你有很多东西要在你的代码中修复。但让我们从最关键的一个开始。这不是我们在 c 中做reallocation 的方式。

if (count!=0){
    struct Telephone* temp = (struct Telephone*)realloc(T,count+1);
}

你在上面的代码中做了什么,你已经释放(realloc 为你做)T 缓冲区并在堆上分配count +1 字节! 这就是你想要做的??

查看 man7 中的 realloc 文档。 realloc

void *realloc(void *ptr, size_t size);

realloc() 函数应该释放指向的旧对象 ptr 并返回一个指向具有指定大小的新对象的指针 按大小... 继续阅读

你应该如何重新分配?

if (count!= 1){
        struct Telephone* temp = (struct Telephone*)realloc(T, count*(sizeof(struct Telephone)));
        if(temp==NULL){ /*we always check the return vale of re/c/m/alloc() */
           .... do work ...
        }
    }

------------------------------------------ --------- 注意 ---------------------------------------- --------------------

我们不会将收到的指针的副本重新分配给函数(c passed by value 中的 evrey 事物)!

所以在重新分配T 指针之后,在你的函数addRecord(生活是美好的)中,realloc 释放了T 指向的先前分配的缓冲区,现在被调用者的指针指向一个 释放缓冲区 !!!他不知道你重新分配!下次他尝试访问 T 指针时,它的 UB

我们如何防止这种情况发生?

双指针T**,并取消引用被调用者指针(重新分配原始指针*T)指向新分配的缓冲区!

被调用者像这样调用addRecord

truct Telephone *T = malloc(...) 
addRecord(&T)

函数签名变为:

void addRecord(struct Telephone **T){
    if (count!=0){
    struct Telephone* temp = (struct Telephone*)realloc(*T,count+1);
    }
    ....
}

------------------------------------------ -------------------------------------------------- -------------------------------------

我不知道你想在这里实现什么!但从修复 realloc 错误开始。

【讨论】:

  • 谢谢我完全错过了那个。我想要做的是有一个动态分配的结构数组,只要用户想要添加一个条目,它的长度就会增加。我正在使用count 跟踪总条目
  • @AROHANAJIT - 欢迎!我鼓励您访问我答案中的链接中的 man7.org 并继续阅读!它会帮助你相信我。最后,如果我的回答对您有帮助,请接受(通过推动答案附近的灰色 V)并投票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
  • 2019-04-20
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
相关资源
最近更新 更多