最近正在处理此练习:
计算一个数组中每个元素的大小。创建一个函数
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;
在这种简单情况下,我分别创建变量和指针并存储地址。第一个代码中令人困惑的事情是,在我看来,我们只是在创建一个指针,而不是指向某个地址。
为什么在这种情况下我无法创建
integer_array
的变量类型并对其进行所有操作(在循环中),然后才将其地址存储在integer_array * ptr
中?
那将是无效的。如果创建局部变量,如下所示:
integer_array* my_count_on_it(string_array* a) {
integer_array local_arr;
// ...
return &local_arr;
}
然后,您不能返回指向它的指针,因为该变量仅在声明它的函数内有效。它在函数的堆栈上,并且当函数返回时,函数的堆栈变为无效。因此,返回类似&local_arr
的内容是错误的,因为它引用的是从函数返回后不应使用的某些内存(这也是未定义的行为)。正确的方法是使用malloc()
,它在堆上分配内存,可以在程序的其他任何地方使用内存,并且不会自动释放(您必须使用free()
手动进行此操作)。
如果是的话,为什么我们要创建指针
sizeof(integer_array)
?
这仅仅是因为您想为上面刚刚用integer_array
定义的结构typedef
分配足够的空间。那不是指针本身的大小,而是指针指向的内存块的大小。
第一个代码中令人困惑的事情是,在我看来,我们只是在创建一个指针,它没有指向某个地址。
最初,在声明时,指针未指向有效内容。然后,在您执行此操作之后:
ptr = malloc(sizeof(integer_array));
指针现在指向堆中有效的某个地址。在该地址,malloc()
保留了足够的空间来容纳integer_array
结构大小的变量。]>
另一件事:强制转换malloc()
的返回值是不必要的,也是错误的,see here作为解释。