【问题标题】:Using struct and point to input and output info使用结构和指向输入和输出信息
【发布时间】:2013-03-31 12:51:37
【问题描述】:

我在 struct 中输入字符串指针时遇到问题。这是我的代码:

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();
}

当我输入第二个学生的名字时,它被打破了?我分配了内存。我想问一下如何为stu指针释放内存?感谢阅读

【问题讨论】:

  • Read a book,因为这不是正确的 C++ 代码。使用 std::string,永远​​不要碰 malloc,删除所有指针和动态分配,不要使用 stdio。
  • 你应该分配给name
  • 往伤口里加盐.. fflush(stdin); 标准未定义。
  • 对我来说最奇怪的部分是在这种混乱中,他实际上正确使用了引用指针参数(尽管他的股票随着随后的malloc() 而立即下跌)。我认识一些在这个概念上苦苦挣扎的专业工程师,他只是走上前标记它=P
  • 看到gets()了吗?那东西太邪恶了,它已被弃用,并且不会在该语言的下一个版本中出现。想想它在做什么,它在哪里它应该得到的数据,以及如何通过使用std::stringstd::getline() 并抛弃malloc() 来避免这种混乱new.

标签: c++ c


【解决方案1】:

在您的程序中有许多可以而且应该改进的地方。一些建议:

  1. 删除char * 成员,将其替换为std::stringYou don't want to do manual memory management for anything unless you really want to.
  2. 放弃愚蠢的scanfprintf,它们不是类型安全Since you are using C++ use std::cin and std::cout and you are much safer than usage with later
  3. 放弃fflush(stdin),在stdout以外的任何地方调用fflushgives you undefined behavior
  4. 在 C++ 中,您通常希望使用 new 而不是 mallocAvoid using dynamic memory allocation at all, if you can。更喜欢使用std::vector

Online Sample
按照上述建议,您的示例可以写成:

#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;        
}

【讨论】:

  • 另外,正如@BLUEPIXY 指出的那样,没有为name 分配空间,因此写入它是未定义的行为。
  • @Beta:#1 负责处理。
  • 是的,但要指出教育学的一个重要错误,即使只是为了开车回家。
【解决方案2】:

正如之前的一些海报所提到的,代码不是“纯”c++,因为它混合了很多 C 和 C++ 特性。就我个人而言,我认为在处理像您这样的 POD 结构时问题较少。

崩溃可能是由gets() 引起的。它假定 char 指针已经分配了合适的容量。当输入字符串长于容量时,它具有未定义的行为。您的容量为 0,因此崩溃。

如果您坚持使用 C 函数,请参阅:Safe Alternative to gets。 否则查找getline()。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 2013-04-13
    • 2016-09-19
    • 1970-01-01
    • 2020-08-08
    相关资源
    最近更新 更多