2017-04-23 53 views
-1

我是一名初學者程序員,我知道C++和JS的基礎知識,但是目前我需要學習C,並且我努力完成一項測試任務。C中的malloc()的任務

基本上,我需要創建一個程序,它將動態分配malloc()的內存。我需要不斷給出學生的課程名稱和成績,直到我決定有足夠的學生。隨着其餘任務我相信我可以處理自己,但現在我的程序在第二次循環後崩潰,我不知道什麼是錯的。

char decision; 
int x = 0; 
char tempname; 
float tempscore; 
char *name = malloc(x *sizeof(char)); 
float *score = malloc(x *sizeof(float)); 

printf("Name and score of the student \n"); 

do{ 
    printf("Name \n"); 
    scanf("%s", &tempname); 
    name[x] = tempname; 
    printf("Score \n"); 
    scanf("%f", &tempscore); 
    score[x] = tempscore; 
    printf("Continue? y/n \n"); 
    scanf("%s", &decision); 
    x++; 
} while(decision=='y'); 

有可能與分配的字符表中存儲一個錯誤,但我真的有此而奮鬥,併爲幫助表示感謝。

+8

'x * sizeof(char)'很好,因爲'x'是'0',所以你正好分配零字節。 – tkausl

回答

3

首先,你應該用鏈表來做到這一點,但是我們會試着用數組來實現。

要開始,您需要創建一個動態大小的指向字符串的指針數組。

我們將使用虛構的內存地址。比方說,我們有4名,它們在內存中排列爲這樣:

0x10000: "Adam" 
0x10010: "Jonathan" 
0x10020: "Mark" 
0x10030: "Zach" 

我們需要一個數組,看起來像這樣:

[0x10000, 0x10010, 0x10020, 0x10030] 

這是你需要的malloc第一陣列。該數組的每個元素的類型爲(char *),因爲該數組持有指向字符串的指針。數組本身的類型是指向這些字符串的指針,因此數組的類型爲(char **)

我們打算稱之爲「names_array」,然後我們將開始跟蹤我們有多少名稱,並適當調整這個數組的大小。

unsigned int num_names = 0; 
char ** names_array = malloc(num_names * sizeof(char *)); 

當我們讀一個名字時,我們需要一些臨時空間來讀取它。我們要改變:

char tempname; 

要:

char tempname[128]; 

現在我們需要把它添加到我們的數組,但我們只對0條目分配的空間。我們需要重新分配內存。有一個功能,realloc,它爲我們做到這一點。 realloc將採用指向某個內存的指針,將內存分配的大小調整爲我們提供的新大小,並且如果需要,則複製到舊內存中。

names_array = realloc(names_array, (num_names + 1) * sizeof(char *)); 

我們需要創建一個新的字符串來保存我們的字符串中tempname,我們要設置在names_array新的價值。我們可以這樣做硬盤的方式:

names_array[num_names] = malloc(strlen(tempname) + 1); 
strcpy(names_array[num_names], tempname); 

或者使用strdup在一個犯規一舉做到這一點對我們來說。

names_array[num_names] = strdup(tempname); 

在此之後,我們通過1增加num_names,並繼續循環。

你的代碼名稱閱讀應該是這個樣子:

scanf("%s", &tempname); 
names_array = realloc(names_array, (num_names + 1) * sizeof(char *)); 
names_array[num_names++] = strdup(tempname); 

您的花車代碼將是類似的,但看起來更像:

scanf("%f", &tempfloat); 
floats_array = realloc(floats_array, (num_floats + 1) * sizeof(float)); 
floats_array[num_floats++] = tempfloat; 

你明白這個代碼是非常重要的是非常不安全的,但是在你開始學習如何安全使用它之前,你似乎需要了解C的工作原理。我希望這有幫助。

+0

謝謝,這讓我更加清楚。 – BigPaws

+0

如果你說「真的應該用結構類型來做這件事」,那麼我會比「真的應該用鏈表做這件事」的評論更開心。你可以使用鏈表來完成;它也可以用數組完成 - 最好是一個結構類型的數組,但是也可以使兩個並行數組工作。 –