2017-04-23 69 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

如果你说“真的应该用结构类型来做这件事”,那么我会比“真的应该用链表做这件事”的评论更开心。你可以使用链表来完成;它也可以用数组完成 - 最好是一个结构类型的数组,但是也可以使两个并行数组工作。 –