“malloc(sizeof(struct a *))”和“malloc(sizeof(struct a))”是否相同?
这个问题是Malloc调用崩溃的延续,但在其他地方有效
我尝试了以下程序,我发现它工作(即没有崩溃 – 这也在上面提到的链接中提到)。 我很幸运能让它工作但是我正在寻找SO专家对于它为何起作用的合理解释?!
以下是使用malloc()
wrt structures
和pointers
分配memory
一些基本知识
-
malloc(sizeof(struct a) * n)
分配n
个类型struct a
元素。 并且,可以使用pointer-to-type-"struct a"
的pointer-to-type-"struct a"
来存储和访问该存储器位置。 基本上是一个struct a *
。 -
malloc(sizeof(struct a *) * n)
分配n
个类型struct a *
元素。 然后,每个元素都可以指向struct a
类型的元素。 基本上malloc(sizeof(struct a *) * n)
分配一个array(n-elements)-of-pointers-to-type-"struct a"
。 并且,可以使用pointer-to-(pointer-to-"struct a")
来存储和访问所分配的存储器位置。 基本上是一个struct a **
。
所以当我们创建一个array(n-elements)-of-pointers-to-type-"struct a"
,就是这样
- 有效将其分配给
struct a *
而不是struct a **
? - 有效访问/取消引用已分配的
array(n-elements)-of-pointers-to-type-"struct a"
使用pointer-to-"struct a"
?
data * array = NULL; if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) { printf("unable to allocate memory \n"); return -1; }
代码段如下:
#include #include int main(void) { typedef struct { int value1; int value2; }data; int n = 1000; int i; int val=0; data * array = NULL; if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) { printf("unable to allocate memory \n"); return -1; } printf("allocation successful\n"); for (i=0 ; i<n ; i++) { array[i].value1 = val++; array[i].value2 = val++; } for (i=0 ; i<n ; i++) { printf("%3d %3d %3d\n", i, array[i].value1, array[i].value2); } free(array); printf("freeing successful\n"); return 0; }
编辑:好的,如果我错误地执行了以下操作
data * array = NULL; if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) {
有没有办法捕获(在编译时使用任何GCC
标志)这种无意识的编程错字,它可能有时会工作,并可能随时爆发! 我用-Wall
编译了这个,发现没有警告!
似乎存在一个根本性的误解。
malloc(sizeof(struct a)* n)分配n个类型struct a元素。
不,这就是通常在这样的电话之后使用它的原因。 malloc(size)
分配size
bytes的内存区域。 你对该地区的所作所为完全取决于你。 唯一重要的是你不要超越分配内存的限制。 在成功的malloc(100*sizeof(float));
之后假设有4个字节的float
和int
以及8个字节的double
malloc(100*sizeof(float));
,您可以使用400字节中的前120个作为15个double
s的数组,接下来的120作为30个float
的数组,然后在其后面放置一个20个char
的数组,并用35填充剩余的140个字节如果你愿意的话。 这是完全无害的定义行为。
malloc
返回一个void*
,它可以隐式地转换为任何类型的指针,所以
some_type **array = malloc(100 * sizeof(data *)); // intentionally unrelated types
非常好,它可能不是你想要的内存量。 在这种情况下很可能是因为指针往往具有相同的大小,而不管它们指向的是什么。
更有可能给你错误的内存量
data *array = malloc(n * sizeof(data*));
就像你拥有它一样。 如果将分配的内存块用作n
data
类型元素的数组,则有三种可能性
-
sizeof(data) < sizeof(data*)
。 那你唯一的问题是你在浪费一些空间。 -
sizeof(data) == sizeof(data*)
。 一切都很好,没有浪费空间,好像你根本没有打字错误。 -
sizeof(data) > sizeof(data*)
。 然后,您将访问在触摸稍后的数组元素时不应访问的内存,这是未定义的行为。 根据各种各样的事情,这可能始终像你的代码是正确的一样工作,立即崩溃与段错误或介于两者之间的任何东西(从技术上讲,它可能以不能有意义地置于这两者之间的方式运行,但这将是不寻常的)。
如果你有意这样做,知道点1或2.适用,这是不好的做法,但不是错误。 如果你无意中这样做,那么无论哪个点适用都是错误的,无害但很难找到1.或2.适用,有害但通常在3的情况下更容易检测。
在你的例子中。 data
是4分。 8个字节(可能),在64位系统上将它们放入1. resp。 2.概率很高,在32位系统上变为2分。 3。
避免此类错误的推荐方法是
type *pointer = malloc(num_elems * sizeof(*pointer));
没有。
sizeof(struct a*)
是指针的大小。
sizeof(struct a)
是整个struct的大小。
这个array = (data *)malloc(sizeof(data *) * n)
为struct data
分配一个sizeof(data*)
( 指针 ),如果你想这样做,你需要一个你的array
作为data** array
。
在您的情况下,您希望指针指向sizeof(data)
,内存中的结构,而不是指向另一个指针。 这将需要data**
(指针指针)。
将它赋给struct a *而不是struct a **是否有效?
好吧,从技术上讲,这样分配是有效的,但取消引用这样的指针是错误的(UB)。 你不想这样做。
有效访问/取消引用已分配的数组(n元素)-of-pointers-to-type-“struct a”使用指针到“struct a”?
不,未定义的行为。