【问题标题】:C Programming - Structs, Pointers, and InitializationC 编程 - 结构、指针和初始化
【发布时间】:2018-03-11 16:04:35
【问题描述】:

我对 C 编程还是很陌生,并且还在学习这门语言。我正在尝试执行以下操作(它是我初始程序代码的缩小版本)。但是每次我尝试初始化counter 时,程序都会崩溃。我尝试设置另一个函数来处理初始化过程,将counter 设置为在set_members 函数中递增,并尝试通过将总计&total 的地址传递给计数器来初始化计数器。但是每次我尝试运行我的程序时,它都会在打印"Hello" 后崩溃。我想我正在尝试错误地初始化counter,因为我不完全理解C 中的pointersstructs。有人可以解释我的初始化过程如何或为什么不正确,并导致我的程序崩溃吗?以及我如何才能正确地做到这一点?谢谢!

typedef struct CharStruct{
    char *names;
}CharStruct;

typedef struct Count{
    CharStruct *arr;
    int counter;
}Count;

typedef struct Members{
    Count *member;
}Members;

typedef struct Test{
    Members people;
}Test;

void set_members(struct Test *person);
void print_total(struct Test *person);

int main(void) {
    printf("Hello\n"); /* prints Hello */
    Test person;
    //person.people.member->counter = 0;
    set_members(&person);
    print_total(&person);
    system("pause");
    return EXIT_SUCCESS;
}

void set_members(struct Test *person)
{
    int total = 0;

    while(total < 10)
    {
        ++total;
    }
    person->people.member->counter = total;
}


void print_total(struct Test *person)
{
    printf("Total Members: %d\n", person->people.member->counter);
}

【问题讨论】:

  • 您没有为成员分配内存。 Member 是一个指针,这个指针指向一些当时不适合你的内存,你需要使用 malloc 分配内存,然后再使用它。 person->people.member = malloc(sizeof(Count));
  • 我不明白set_members中的while循环的含义,你为什么要这样做?
  • 我也不懂你的结构,你用这些结构建模什么样的数据? Test 包含 Members 结构,Members 包含指向 Count 的指针,其中包含 CharStruct 的指针?你想解决什么问题?

标签: c pointers memory-management struct malloc


【解决方案1】:

当你看看:

typedef struct Members{
    Count *member;
}Members;

请注意member 是一个指向Count type 对象的指针。 为了能够对该对象进行操作,该对象必须存在。它的内存必须动态或静态分配。否则,您的程序的行为未定义。

检查示例程序中完成的内存分配:

#include <stdio.h>
#include <stdlib.h>

typedef struct CharStruct{
    char *names;
}CharStruct;

typedef struct Count{
    CharStruct *arr;
    int counter;
}Count;

typedef struct Members{
    Count *member;
}Members;

typedef struct Test{
    Members people;
}Test;

void set_members(struct Test *person)
{
    int total = 0;
    while(total < 10){
        ++total;
    }
    person->people.member->counter = total;
}

void print_total(struct Test *person)
{
    printf("Total Members: %d\n", person->people.member->counter);
}

int main(void) {
    printf("Hello!\n"); /* prints Hello */ 
    Test person;     
#if 0 // allocate memory on stack
    Members m;
    Count   c;
    // use declared variables 
    person.people = m;  
    m.member = &c; 
#else    
    // or dynamic alocation
    person.people.member = malloc(sizeof(Count)); 
#endif

    set_members(&person);
    print_total(&person);

    person.people.member->counter = 77;
    print_total(&person);

    free(person.people.member);

    //system("pause");
    return EXIT_SUCCESS;
}

输出:

Hello!                                                                                                                                     
Total Members: 10                                                                                                                          
Total Members: 77

Count 类型对象的内存,其中类型为Count

typedef struct Count{
    CharStruct *arr;
    int counter;
}Count;

分配者:

malloc(sizeof(Count));

值得强调的是,您可以使用int counter,但CharStruct *arr 指向未定义的内存位置。

同样,为了安全地使用成员arr,它必须指向CharStruct 类型的有效对象。您应该为CharStruct 分配内存。这还不是全部。一旦你有了对象CharStruct,它就有了char *names指向字符串的指针。如果你想使用names,它应该指向有效的字符串!

您的带有指针的嵌套结构链需要非常小心地处理内存分配和释放。请注意潜在的内存泄漏或未初始化的指针。这些是许多 C 程序员遇到的最常见的问题之一。

【讨论】:

  • 谢谢!这更有意义。我没有意识到我没有提前创建对象并分配内存来设置counter。另外,感谢您包含注意内存泄漏和分配/释放的注释。这对我来说很重要。
【解决方案2】:

person.people.member 是一个未初始化的指针。它有一些垃圾值,可能是程序不允许访问的某个内存位置的地址。

正如其他人所说,取消引用未初始化的指针会调用未定义的行为。

您需要为struct Count 分配内存并将其地址分配给person.people.member,然后再向其写入值。

你可以的

person.people.member = malloc(sizeof(struct Count));

main() 声明person 之后,或者做

person->people.member = malloc(sizeof(struct Count));

set_members() 之前person-&gt;people.member-&gt;counter = total;

一旦你用完它,别忘了释放内存

free(person->people.member);

其他指针 person.people.member-&gt;arrperson.people.member-&gt;arr-&gt;names 也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多