2

構造体への文字列ポインタの入力に問題があります。これは私のコードです:

typedef struct{
        char *name;
        int age;      
}stu;

void allocate(stu* &s, int n){
     s = (stu*) malloc(n * sizeof(stu));
     if(s == NULL){
          printf("\nNot enought memory!");
          exit(1);
     }     
}
// Input info
void input_info(stu* &s, int n){
     void input(stu &s); //prototype
     for(int i = 0; i < n; i++){
             printf("\n-- Student #%d:", i+1);
             input(*(s+i));
     }    
}

void input(stu &s){
     fflush(stdin);
     printf("\nEnter student's name: ");
     gets(s.name);
     printf("\nEnter student's age: ");
     scanf("%d", &s.age);
}
// End input

//Output info
void output_info(stu* s, int n){
     void output(stu s); //prototype
     for(int i = 0; i < n; i++){
             printf("\n-- Student #%d:", i+1);
             output(*(s+i));
     }
}

void output(stu s){
     printf("\nName: %s", s.name);
     printf("\nAge: %d", s.age);
}
//End output

int main(){
    stu* s;
    int n;
    printf("How many students you want to input?: ");
    scanf("%d", &n);
    allocate(s, n);
    input_info(s, n);
    output_info(s, n);
    getch();
}

2 番目の生徒の名前を入力すると壊れますか? メモリを割り当てました。そして、stuポインタのメモリを解放する方法を尋ねたいですか? 読んでくれてありがとう

4

2 に答える 2

4

プログラムには、改善できる点と改善すべき点がたくさんあります。いくつかの提案:

  1. メンバーを削除し、 にchar *置き換えstd::stringます。本当に必要でない限り、手動でメモリ管理を行う必要はありません。
  2. ばかげたscanfandを削除します。これらはタイプ セーフprintfではありません。C++ を使用しているため、and を使用すると、 later を使用するよりもはるかに安全ですstd::cinstd::cout
  3. をドロップし、以外のものをfflush(stdin)呼び出すと、未定義の動作が発生します。fflushstdout
  4. C++ では、通常、newand ではなく を使用しますmalloc可能であれば、動的メモリ割り当てを使用しないでください。代わりにa を使用することをお勧めしますstd::vector

オンライン サンプル:
上記の提案に従って、例は次のように記述できます。

#include<string>
#include<vector>
#include<iostream>

typedef struct
{
    std::string name;
    int age;      
}student;

// Input info
void input_info(std::vector<student> &s)
{ 
    student obj;
    std::cout<<"\nEnter Students name";
    std::cin>>obj.name;
    std::cout<<"\nEnter Students age";
    std::cin>>obj.age;
    s.push_back(obj);
}

// Output info
void output_info(const std::vector<student> &s)
{
    for (auto itr = s.cbegin(); itr != s.cend(); ++itr)
    {
        std::cout<<"\nName:"<< itr->name;
        std::cout<<"\nAge:"<< itr->age;
    }
}

int main()
{
    int n;
    std::cout<<"How many students you want to input?\n";
    std::cin>>n;
    std::vector<student>s;
    for(int i = 0; i<n; i++)
    {
        input_info(s);
    }
    output_info(s);
    return 0;        
}
于 2013-03-31T13:13:16.407 に答える
0

以前の投稿者の一部が言及したように、コードは多くの C と C++ の機能が混在しているため、「純粋な」C++ ではありません。個人的には、あなたのような POD 構造体を扱うときの問題は少ないと思います。

クラッシュはおそらく gets() によって引き起こされます。char ポインターが適切な容量で既に割り当てられていることを前提としています。入力文字列が容量よりも長い場合、未定義の動作が発生します。容量が 0 であるため、クラッシュします。

C 関数の使用を主張する場合は、次を参照してください: gets の安全な代替。それ以外の場合は、getline() を検索します。

于 2013-03-31T13:24:41.303 に答える