有扫描问题

时间:2015-03-23 20:35:13

标签: c scanf

我自己一直在研究一些C,我想知道我的分段错误是否与我试图将*人添加到名为学生的动态数组的方式有关。 这最初是作为一种尝试学习如何使用动态数组的方法开始的,但是我很难理解我是如何无法绕过这个scanf故障我的程序。我包括了我所做的一切,但我怀疑我的问题是在主要的,特别是scanf。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//ARR_LEN 
#define ARR_LEN 5
#define STR_LEN 15
//STUDENT STRUCT
typedef struct{
  int ID;
  char *name;
}Student;

typedef struct{
  Student *array;
  size_t used;
  size_t size;
}Array;

void initArray(Array *a, size_t initialSize){
  //ALLOCATING INITIAL SPACE
  a->array = (Student *)malloc(initialSize * sizeof(Student));

  a->used = 0;
  a->size = initialSize;

  //INITIALIZES ALL VALUES OF THE ARRAY TO 0
  for(unsigned int i = 0; i<initialSize; i++){
    memset(&a->array[i],0,sizeof(Student));
  }
}

  //ADDING A STUDENT ELEMENT INTO ARRAY
void insertArray(Array *a,Student element){
  if(a->used == a->size){
    a->size *= 2;
    a->array = (Student *)realloc(a->array,a->size * sizeof(Student));
  }

//Copy Name
a->array[a->used].name = (char*)malloc(strlen(element.name) + 1);
strcpy(a->array[a->used].name, element.name);

//Copy ID
a->array[a->used].ID=element.ID;


a->used++;
}

void freeArray(Array *a){
 for(int i=0;i<a->used;i++){
    free(a->array[0].name);
    a->array[0].name=NULL;
 }

//Freeing the array
 free(a->array);
 a->array = NULL;

 a->used = 0;
 a->size = 0;
}




int main(int argc, const char * argv[]){

char choice;
Array student;
Student *person;
char* firstName;
firstName = (char *)malloc(100*sizeof(char));
int* number;
 number = (int *)malloc(10*sizeof(int));
printf("Would you like to make a list of people? (y/n): ");
scanf("%c \n",&choice);
    while(choice == 'y'){
        initArray(&student, 5);
        printf("\nPlease enter students name: ");
        scanf("%s \n",&firstName);
                printf("NAME ENTERED: %s\n",firstName);
//      fgets(firstName,100,stdin);
        printf("\nPlease enter students ID: ");
        scanf("%i \n",number);
//      fgets(number,100,stdin);
                    for(int i = 0; i<ARR_LEN;i++){
                person->name = firstName;
                person->ID = (int)number;
                        insertArray(&student,*person);
                printf("Would you like to add another? (y/n): \n");
            }
    }   
printf("Would you like to print the list of people? (y/n): ");
scanf("%c \n",&choice);
    if(choice == 'y'){
        for(int x=0;x<sizeof(student);x++){
            printf("Name: %s", student.array[x].name);
        }       
    }
}

现在给予应有的信用。我从&#34;卡萨布兰卡&#34;中抓住了整体动态阵列方案。并且看到我是否可以用它来全面了解阵列是如何构建的。他/她的帖子可以在这里找到:C dynamically growing array

1 个答案:

答案 0 :(得分:0)

这里有一个错误:

void freeArray(Array *a){
    for(int i=0;i<a->used;i++){
        free(a->array[0].name);
        a->array[0].name=NULL;
    }
    ...
}

您反复释放第一个元素,但由于您将其设置为NULL,因此对free()的后续调用无效。其他元素名称永远不会被释放。

将此代码更改为:

void freeArray(Array *a) {
    for(int i = 0; i < a->used; i++) {
        free(a->array[i].name);
        a->array[i].name = NULL;
    }
    ...
}

这里还有另一个问题:

   scanf("%s \n",&firstName);

您不限制输入大小。如果用户输入长名称,这可能会导致缓冲区溢出。请改用:

   scanf("%99s \n",&firstName);

这是一个更重要的错误:

    Student *person;
    ...
    for (int i = 0; i<ARR_LEN;i++) {
        person->name = firstName;
        person->ID = (int)number;
        insertArray(&student,*person);
        ...

人应该是结构,而不是指针:

    Student person;
    ...
    for (int i = 0; i<ARR_LEN;i++) {
        person.name = firstName;
        person.ID = (int)number;
        insertArray(&student, person);
        ...

另一个坏人:

    for(int x=0;x<sizeof(student);x++){
        printf("Name: %s", student.array[x].name);
    }       

您循环使用sizeof(student)元素而不是student.used

请改用:

    for (int x = 0; x < student.used; x++){
        printf("Name: %s\n", student.array[x].name);
    }       

代码中还有许多问题:例如,您没有处理内存不足的情况。