【问题标题】:Error when adding another record to dynamic memory database将另一条记录添加到动态内存数据库时出错
【发布时间】:2015-10-06 08:14:40
【问题描述】:

我的任务是用一些数据初始化标题中的结构。然后使用指针,通过 malloc-ing 更大/更小的块并复制数据来添加/删除数据。

目前,我的 addRecord 函数不起作用,因为它似乎总是添加相同的废话(记录号 1 的一部分):

名字 =

Fire Number = attan(似乎是曼哈顿的一部分)

Street = ork(似乎是纽约的一部分)

City = cret(似乎是 Secret 的一部分)

State = tan(似乎是曼哈顿的一部分)

我做错了什么?

我的标题:

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

struct structPointer{
    char name[51];
    char fireNumber[11];
    char street[26];
    char city[26];
    char state[26];
};

我的c文件:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "myData.h"

struct structInit *sP;
struct structInit *sSP;
int recordNumber = 0;
int numberOfAccesses = 0;

int main(void) {
    sP = (struct structInit *) malloc(5 * sizeof(struct structInit));
    sSP = sP;

    memcpy(sP->name,"Adam Baum",51);
    memcpy(sP->fireNumber,"N1234",11);
    memcpy(sP->street,"Top Secret",26);
    memcpy(sP->city,"Manhattan",26);
    memcpy(sP->state,"New York",26);
    sP++;
    recordNumber++;
    memcpy(sP->name,"Adam Zapel",51);
    memcpy(sP->fireNumber,"S4321",11);
    memcpy(sP->street,"Throat",26);
    memcpy(sP->city,"Manhattan",26);
    memcpy(sP->state,"New York",26);
    sP++;
    recordNumber++;
    memcpy(sP->name,"Al Bino",51);
    memcpy(sP->fireNumber,"W1234",11);
    memcpy(sP->street,"White",26);
    memcpy(sP->city,"Anchorage",26);
    memcpy(sP->state,"Alaska",26);
    sP++;
    recordNumber++;
    memcpy(sP->name,"Anne Teak",51);
    memcpy(sP->fireNumber,"E4321",11);
    memcpy(sP->street,"Oak",26);
    memcpy(sP->city,"Woodville",26);
    memcpy(sP->state,"Wisconsin",26);
    sP++;
    recordNumber++;
    memcpy(sP->name,"Barb Dwyer",51);
    memcpy(sP->fireNumber,"N1234",11);
    memcpy(sP->street,"Keepout",26);
    memcpy(sP->city,"Kilgore",26);
    memcpy(sP->state,"Texas",26);
    recordNumber++;
    sP = sSP;

    int sel;
    while (1){
    printf("MENU\n");
    printf("=====\n");
    printf("1. Print All Records\n");
    printf("2. Print Number of Records\n");
    printf("3. Print Size of Database\n");
    printf("4. Add Record\n");
    printf("5. Delete Record\n");
    printf("6. Print Number of Accesses to Database\n");
    printf("7. Exit\n");
    printf("=====\n");
    printf("Enter selection: ");
    scanf("%d", &sel);
    printf("\n");
        switch(sel){
            case 1:
                numberOfAccesses++;
                printAllRecords(sP);
                break;
            case 2:
                numberOfAccesses++;
                fprintf(stderr,"There are a Total of %d records.\n\n", recordNumber);
                break;
            case 3:
                numberOfAccesses++;
                printSizeOfDatabase(sP);
                break;
            case 4:
                numberOfAccesses++;
                sP = sSP;
                addRecord(sP);
                break;
            case 5:
                numberOfAccesses++;
                deleteRecord(sP);
                break;
            case 6:
                numberOfAccesses++;
                fprintf(stderr,"The total number of Accesses is %d\n\n", numberOfAccesses);
                break;
            case 7:
                exit(0);
            default:
                printf("Error: Input was not a valid selection.\n\n");
                break;
        }
    }
return 0;
}

int printAllRecords(struct structInit *structPointer){
    int i;
    structPointer = sSP;
    printf("All Records: \n");
    for(i=1;i<=recordNumber;i++){
    printf("Record Number: %d\n", i);
    fprintf(stderr, "Name = \%s\n", structPointer-> name);
        fprintf(stderr, "Fire Number = \%s\n", structPointer-> fireNumber);
        fprintf(stderr, "Street = \%s\n", structPointer-> street);
        fprintf(stderr, "City = \%s\n", structPointer-> city);
        fprintf(stderr, "State = \%s\n\n", structPointer-> state);
        structPointer++;
    }
    return 1;
}

int printSizeOfDatabase(struct structInit *structPointer) {
    int size = 0;
    int i;
    for (i=1;i<=recordNumber;i++) {
    size += sizeof(structPointer->name);
    size += sizeof(structPointer->fireNumber); 
    size += sizeof(structPointer->street);
    size += sizeof(structPointer->city);
    size += sizeof(structPointer->state);
    structPointer++;
        }
    fprintf(stderr, "The size of the database is %d bytes.\n\n", size);
    return size;
}

int addRecord(struct structInit *structPointer){
    char entryName;
    char entryFireNumber;
    char entryStreet;
    char entryCity;
    char entryState;
    recordNumber++;
    struct structInit *theStruct;
    theStruct = (struct structInit *) malloc ((recordNumber+1) * sizeof(struct structInit));
    int i;
    for (i=1;i<recordNumber;i++){
        memcpy(theStruct->name,structPointer->name,51);
        memcpy(theStruct->fireNumber,structPointer->fireNumber,11);
        memcpy(theStruct->street,structPointer->street,26);
        memcpy(theStruct->city,structPointer->city,26);
        memcpy(theStruct->state,structPointer->state,26);
        /*if(i==recordNumber){
            theStruct++;}
        else{
            theStruct++;
            structPointer++;}*/
    theStruct++;
    structPointer++;
    }
    theStruct++;

    printf("Enter the Name of the New Record: \n");
    scanf("%s",&entryName);
    memcpy(theStruct->name,&entryName,51);
    printf("Enter the Fire Number of the New Record: \n");
    scanf("%s",&entryFireNumber);
    memcpy(theStruct->fireNumber,&entryFireNumber,11);
    printf("Enter the Street of the New Record: \n");
    scanf("%s",&entryStreet);
    memcpy(theStruct->street,&entryStreet,26);
    printf("Enter the City of the New Record: \n");
    scanf("%s",&entryCity);
    memcpy(theStruct->city,&entryCity,26);
    printf("Enter the State of the New Record: \n");
    scanf("%s",&entryState);
    memcpy(theStruct->state,&entryState,26);
    structPointer=theStruct;
    printf("Record has been added.\n\n");
    return 0;
}

int deleteRecord(struct structInit *structPointer){
    struct structInit *anotherStruct;
    anotherStruct = (struct structInit *) malloc ((recordNumber+1) * sizeof(struct structInit));
    int i;
    for(i=0;i<5;i++){
    memcpy(anotherStruct->name,structPointer->name,51);
    memcpy(anotherStruct->fireNumber,structPointer->fireNumber,11);
    memcpy(anotherStruct->street,structPointer->street,26);
    memcpy(anotherStruct->city,structPointer->city,26);
    memcpy(anotherStruct->state,structPointer->state,26);
    structPointer++;
    }
    structPointer=anotherStruct;
    recordNumber--;
    printf("Record has been deleted.\n\n");
    return 0;
}

【问题讨论】:

  • 哪种语言,C 或 C++?编辑标签以反映正确的标签,它们不是一回事。
  • 您所有的memcpys 都未定义,addRecord 中的scanfs 也是如此。
  • @SamiKuhmonen 抱歉,一定是不小心点击了两者。
  • @molbdnilo 你能再解释一下吗?
  • @Specerion 有大量关于如何使用scanf、memcpy 和strncpy 的信息。这个问题的完整答案对于 SO 来说太长而且太具体了。我建议你先学习编写一些小程序进行练习。

标签: c pointers struct dynamic-memory-allocation


【解决方案1】:

一目了然:

scanf 的 %s 格式说明符指定指向 char 数组的第一个元素的指针。
您正在传递一个指向 one 字符的指针。
程序没有完全崩溃只是运气不好。

你想要的

char entryName[51];
/* ... */
printf("Enter the Name of the New Record: \n");
scanf("%s", entryName);

其余输入类似。

将memcpy 替换为strncpy - 您不应从源对象外部复制任何内容。

如果您使用realloc,您可以在展开表格时摆脱整个复制循环。

分配给参数不会修改您传入其值的变量的值。
这对于指针和其他一切都是如此。
如果你想修改一个变量,传递一个指向它的指针:

int addRecord(struct structInit **structPointer)
{
   /* ... */
   *structPointer = theStruct;
   /* ... */
}

你不需要在结构之间做一个成员memcpy - 事实上你根本不需要memcpy,因为分配有效:

struct structInit a = /* ... */;
struct structInit b = /* ... */;
a = b; /* OK */

您需要决定是使用全局变量还是参数。
特别是,printAllRecords 完全忽略了其参数的值。

deleteRecord 假设您的表中有 5 条记录。

您也可以将printSizeOfDatabase 替换为:

int printSizeOfDatabase() {
    int size = recordNumber * sizeof(struct structInit);
    fprintf(stderr, "The size of the database is %d bytes.\n\n", size);
    return size;
}

【讨论】:

    【解决方案2】:

    您可以在 add 函数中使用 realloc。 typedef 将使程序更易于阅读。 请将此行添加到 mydata.h 的末尾

      typedef struct structPointer structInit;
    

    那么在main()之前就变成了

    结构初始化 *sP; structInit *sSP;

    然后 printAllRecords 变成: int printAllRecords(structInit *structPointer)

    然后打开调试器并阅读消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-24
      • 2019-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多