C取消引用指针

时间:2018-12-19 13:55:57

标签: c pointers memory

我开始学习C,但我不知道为什么应用程序持续崩溃。

#include <stdio.h>
#include <string.h>

typedef struct
{
    char name[50];
    int age;
}person;

void initPerson(person *aPerson, char name[50], int age)
{
    strcpy(aPerson->name, name); // <- causes a crash
    aPerson->age = age; // <- causes a crash
    printf("%s", aPerson->name);
}

int main()
{
    person *myPerson;
    initPerson(myPerson, "Oscar", 45);

    printf("%s, %i", myPerson->name, myPerson->age);
    return 0;
}

我已标记出导致崩溃的行。有人可以告诉我是什么问题吗?

1 个答案:

答案 0 :(得分:8)

“ ...应用程序不断崩溃,......有人可以告诉我是什么问题吗?”
是的,您的程序正在尝试写入它不拥有的存储位置。

如果必须使用指向person的指针,请在使用前创建一些内存:

int main()
{
    person *myPerson = calloc(1, sizeof(*myPerson));
    if(!myPerson) return 0; //test if failed

    initPerson(myPerson, "Oscar", 45);

    printf("%s, %i", myPerson->name, myPerson->age);
    free(myPerson);//free memory
    return 0;
}

或者,您可以简单地通过person的非指针实例的地址(使用&)来获得相同的结果:

int main()
{
    person myPerson = {0};

    initPerson(&myPerson, "Oscar", 45);
    printf("%s, %i", myPerson.name, myPerson.age);
    return 0;
}

声明:

person *myPerson;

仅创建未初始化的指针,在创建时不指向内存中的任何特定位置。此时唯一使用的空间是指针本身sizeof(person *)。 (分别针对32位或64位目标,分别为4或8字节。)在以这种方式使用指针变量之前,必须通过调用_ void *calloc(size_t nitems, size_t size) _或<家庭。以这种方式创建的内存将指针的地址设置为与nitems*size个字节的连续块的第一个字节重合的存储位置,在此情况下,myPerson个字节专用于此。以这种方式分配的内存称为堆内存,并且在不再需要时,必须通过调用 free() 显式释放该内存。通常,仅当在编译时不知道特定变量的内存要求时才建议使用此方法

但声明:

person myPerson;

静态(或自动,具体取决于创建时间/位置。)为{{1 }},位于内存中的地址sizeof(person)上。以这种方式创建的内存称为堆栈内存。因为将myPerson&myPerson)的地址作为参数传递给myPerson,并且完成了与动态分配的内存相同的操作(如上所述),所以这是一个更简单的选择因为它不需要创建或释放任何内存。

Stack and heap memory explained.

Discussion on automatic, static and dynamic memory allocation