malloc需要sizeof运算符吗?

时间:2015-06-12 00:51:40

标签: c

在这个程序(C,而不是C ++)中,为什么无论使用sizeof运算符,malloc总是返回正确的大小?

var temp_points;
for(var i=0; i<polylines.length; i++){
  for(var j=0; j<polylines[i].length; j++){
    temp_points.push(new google.maps.LatLng(polylines[i][j][0], polylines[i][j][1]));
  }
}
//calculate using temp_points;

输出结果为:

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

int main(void) {
    char *c = malloc(3);
    short *s = malloc(3); /* or malloc(3 * sizeof(short))? */
    int *i = malloc(3);   /* or malloc(3 * sizeof(int))? */
    long *l = malloc(3);  /* or malloc(3 * sizeof(long))? */

    printf("%p\n", c++);
    printf("%p\n", c++);
    printf("%p\n", c++);

    printf("---\n");

    printf("%p\n", s++);
    printf("%p\n", s++);
    printf("%p\n", s++);

    printf("---\n");

    printf("%p\n", i++);
    printf("%p\n", i++);
    printf("%p\n", i++);

    printf("---\n");

    printf("%p\n", l++);
    printf("%p\n", l++);
    printf("%p\n", l++);

    return 0;
}

我错过了什么吗?

4.0.4-303.fc22.x86_64 clang版本3.5.0(标签/ RELEASE_350 / final) 目标:x86_64-redhat-linux-gnu 线程模型:posix

5 个答案:

答案 0 :(得分:10)

long *l = malloc(3);

这分配(或者更确切地说是尝试分配)3 bytes

通常malloc()实际上会分配比您请求更多的内容,用于校准和簿记。因此,在调用malloc(3)之后,您可能能够在分配的内存中存储3个long值。但这并不能保证。

是的,您确实需要sizeof

最好的写法是:

long *l = malloc(3 * sizeof *l);

通过使用指针所指向的大小(sizeof *l),您不必指定类型long两次,如果类型稍后更改,代码将不会中断。

更好:

long *l = malloc(3 * sizeof *l);
if (l == NULL) {
    /* malloc failed, recover or bail out */
}

如果您愿意,可以将其写为:

long *l = malloc(3 * sizeof(*l));

但是没有必要使用额外的括号,大小sizeof是一元运算符,而不是函数。

printf("%p\n", l++);
printf("%p\n", l++);
printf("%p\n", l++);

增加指针使其指向它指向的类型的大小。 long显然是系统上的8个字节,因此这将使l至少提前24个字节,远远超过您从malloc请求的3个字节。结果是未定义的行为。

通过递增l,您丢失了malloc返回的原始值;当你需要拨打free()时,你需要这个。

最后,%p格式说明符需要类型为void*的参数。传递不同的指针类型可能会“起作用”,但你真的应该将其转换为void*

printf("%p\n", (void*)l++);

答案 1 :(得分:5)

  

我错过了什么吗?

是的,你完全忽略了这一点。

您正在测试指针算术,它是根据指向类型的大小定义的。这与malloc()分配的内存量完全无关,甚至与所讨论的指针是否指向有效地址完全无关。

答案 2 :(得分:4)

递增指针会将存储的地址增加基本类型的大小。它不依赖于指针指向的内容。

答案 3 :(得分:2)

增加指针时递增的字节数仅基于其类型 - 例如如果将int*递增1,则会将地址增加4个字节。这与mallocsizeof或其他任何内容无关。

你会发现如果你开始在那些指针中存储值,你会遇到奇怪的行为,因为你没有分配足够的空间来存储3 short或3 int s或3 long s。

答案 4 :(得分:2)

你已成为谬误的牺牲品。您没有分析malloc返回的内容,您看到增量知道如何根据变量类型的大小正确递增指针。没有关于malloc调用的信息告诉你实际分配了多少RAM。