【问题标题】:Allocating memory for structured pointer为结构化指针分配内存
【发布时间】:2020-04-22 04:10:00
【问题描述】:

最近正在处理这个练习:

计算数组中每个元素的大小。创建一个函数my_count_on_it,接收一个字符串数组作为参数,返回一个数组,每个字符串的长度。

结构:

typedef struct s_string_array {
    int size;
    char **array;
} string_array;

typedef struct s_integer_array {
    int size;
    int *array;
} integer_array;

所以正确的答案是:

#include <string.h>

integer_array *my_count_on_it(string_array *a) {
    integer_array *ptr;

    ptr = (integer_array *)malloc(sizeof(integer_array));
    ptr->size = a->size;
    ptr->array = (int*)malloc(ptr->size * sizeof(int));

    for (int i = 0; i < a->size; i++) {
        ptr->array[i] = strlen(a->array[I]);
    }

    return ptr;
}

我知道指针存储了某个变量的地址,但我不明白为什么在这种情况下我不能创建integer_array 的变量类型并用它来执行所有操作(在循环中),只有这样将其地址存储在integer_array * ptr?还有一个问题,如果是这样,为什么我们要创建指针sizeof(integer_array)

例如:

int variable = 5;
int *ptr = &variable;

在这个简单的例子中,我分别创建变量和指针并存储地址。第一个代码中令人困惑的地方是,在我看来,我们只创建了一个指针,它并没有指向某个地址。

【问题讨论】:

    标签: c pointers memory malloc structure


    【解决方案1】:

    为什么在这种情况下我不能创建integer_array 的变量类型并使用它执行所有操作(在循环中),然后才将其地址存储在integer_array * ptr 中?

    那将是无效的。如果你创建一个局部变量,像这样:

    integer_array* my_count_on_it(string_array* a) {
        integer_array local_arr;
    
        // ...
    
        return &local_arr;
    }
    

    那么你不能返回一个指向它的指针,因为这个变量只有在定义的函数返回之前才有效。它在函数的栈上,当函数返回时,函数的栈就失效了。因此,返回 &amp;local_arr 之类的内容是错误的,因为它指的是从函数返回后不应使用的一些内存(这也是未定义的行为)。正确的做法是使用malloc(),它在堆上分配内存,可以在程序的其他任何地方使用,并且不会自动释放(你必须手动使用free())。

    如果是这样,为什么我们要创建一个指针 sizeof(integer_array)

    这仅仅是因为您想为刚才用typedef 定义的结构integer_array 分配足够的空间。这不是指针本身的大小,而是指针指向的内存块的大小。

    第一个代码中令人困惑的地方是,在我看来,我们只创建了一个指针,它并没有指向某个地址。

    最初,当声明时,指针没有指向有效的东西。然后,在你这样做之后:

    ptr = malloc(sizeof(integer_array));
    

    指针现在指向堆中的某个有效地址。在该地址处,malloc() 保留了足够的空间来保存 integer_array 结构大小的变量。

    === Before malloc(): =========================
    
    ptr = ????? -------> INVALID
    
    === After malloc(): ==========================
    
                          Memory
                          |   ...         | ...
    ptr = 0x120 ------->  +---------------+ 0x120
                          | space for     | 
                          | integer_array |
                          +---------------+ 0x128
                          |   ...         | ...
    

    还有一点:强制转换malloc() 的返回值是不必要且错误的,see here 解释一下。

    【讨论】:

    • 局部变量仅在声明它的函数中无效。您可以将其地址传递给其他函数,并且在这些函数中也有效。该对象具有自动存储期限。它一直存在,直到其关联块的执行结束,并且只要它存在,它就可以被任何地方的任何函数使用。此处使用的正确概念是 scope(标识符可见)和 storage durationlifetime(在程序执行期间对象存在于计算的 C 模型)。将某些东西称为“局部变量”会混淆基本概念。
    猜你喜欢
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2017-01-03
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多