簡體   English   中英

純C-傳遞結構體指針的引用

[英]Pure C - Passing the reference of a pointer of a struct

我創建了一個程序,該程序通過鍵盤從學生信息中加載數據庫,之后我試圖創建一個選項以向該數據庫添加新的學生注冊

該結構包括

typedef struct {
    long unsigned int aem;
    char name[64];
    short unsigned int lessonsToPass;
} Registration;

我已經在主函數上創建了一個指針

int i, sizeOfDatabase;
Registration *database
scanf("%d", &sizeOfDatabase);
database = (Registration*) malloc(sizeOfDatabase * sizeof(Registration));
for(i = 0; i < sizeOfDatabase; ++i){
    scanf("%lu%63s%hu", &(database+i)->aem, (database+i)->name, &(database+i)->lessonsToPass);
    for(tmp = (database+i)->name; (*tmp=toupper(*tmp)); ++tmp);
}

所以基本上我是從鍵盤上獲取數據庫並將名稱改成大寫的

之后,我要調用一個函數來添加新的注冊

void add(char *aem, char *name, char *lessonsToPass, int currentDatabaseSize, Registration **database){
    char *tmp;
    int newSize = currentDatabaseSize + 1;
    *database = (Registration*) realloc(*database, newSize * sizeof(Registration));
    for(tmp = name; (*tmp=toupper(*tmp)); ++tmp);
    (*database + newSize)->aem = atoi(aem);
    strcpy((*database + newSize)->name, name);
    (*database + newSize)->lessonsToPass = atoi(lessonsToPass);
}

char *名稱從不大於64,並且我仍然收到編譯錯誤malloc(): corrupted top size

我想念什么?

(*database + newSize)->aem = atoi(aem);

剛剛注銷了分配的塊,因為newSize包含分配的記錄數,包括現在正在創建的記錄數。 正確的代碼:

(*database + newSize - 1)->aem = atoi(aem);
strcpy((*database + newSize - 1)->name, name);
(*database + newSize - 1)->lessonsToPass = atoi(lessonsToPass);

您已經選擇了一些不尋常的習慣用法來表示您要嘗試做的事情。 這是更易於理解並解決問題的代碼。 注意我假設您有一個現代的C編譯器。 您的代碼樣式為C89。 那是1989年。如果可以選擇,則應該使用較新的C語言功能。

首先使用字符串大寫方法來防止重復代碼:

void strtoupper(char *s) {
  for (char *p = s; *p; ++p) *p = toupper(*p);
}

現在剩下的:

int sizeOfDatabase;
Registration *database;

scanf("%d", &sizeOfDatabase);
database = malloc(sizeOfDatabase * sizeof *database); // NO CAST HERE!
for (int i = 0; i < sizeOfDatabase; ++i){
  Registration *r = database + i;
  scanf("%lu%63s%hu", &r->aem, r->name, &r->lessonsToPass);
  strtouper(r->name);
}

您應該傳遞一個指向數據庫大小的指針 ,以便add方法可以更新它。 以正確的方式調用realloc ,效率很低,因為每次調用都需要與整個數據庫大小成比例的時間。 如果它變大了,您會后悔的。 但這是一個好點,我們將忽略。

void add(char *aem, char *name, char *lessonsToPass,
  Registration **database, int *dbSize) {
  int i = (*dbSize)++; // Increase db size by 1 and get new element's index.
  Registration *db = *database = realloc(*database, *dbSize * sizeof **database);
  Registration *r = db + i;
  strcpy(r->name, name);  // DON'T MODIFY THE INPUT.
  strtoupper(r->name);
  r->aem = atoi(aem);
  r->lessonsToPass = atoi(lessonsToPass);
}

我希望這是有道理的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM