为什么Malloc分配的内存比我要求的多?

时间:2014-01-03 14:51:18

标签: c arrays pointers struct malloc

我必须定义一个动态的struct数组。但是当我以这种方式定义数组时:

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

struct user {
   int id;
   char *name;
   int *friendlist;
   int *blocklist;
   char *university;
   int age;
};

int main (void)
{
    struct user *Userlist;
    Userlist = malloc(sizeof(Userlist) * 10);
    Userlist[2815].name="Someone";
    printf("%s\n", Userlist[2815].name );
    return 0;
}

我为10个Userlist结构定义了内存。它存储2815结构。但是当我尝试将值赋给第2816个结构时,它会显示“分割错误。核心转储”。它必须存储我分配的10个结构,但为什么它存储2815个结构?

3 个答案:

答案 0 :(得分:3)

malloc调用仅留出您指定的存储量(struct user的10个元素)。 C不对数组访问进行任何边界检查;该语言假设您知道您的阵列有多大,并且您足够聪明,不会超越它。

尝试访问超出数组末尾的项目会调用未定义的行为,它不会 导致段错误或崩溃。事实上,索引2815的内存没有受到保护或被用于任何“重要”的东西(尽管它可能影响了其他地方的执行)。

供参考,以下是“未定义行为”的定义,取自the latest standard

3.4.3

1 未定义的行为
在使用不可移植或错误的程序结构或错误数据时, 本国际标准没有要求

2注意可能的未定义行为范围包括完全忽略不可预测的情况 结果,在翻译或程序执行过程中以文件化的方式表现 环境(有或没有发出诊断信息),终止翻译或 执行(发出诊断信息)。

3示例未定义行为的示例是整数流上的行为

答案 1 :(得分:1)

它没有malloc 2815结构。事实上它只有mallocs 10指针! (在典型系统上大约80个字节)您没有因为偶然性而得到故障,而不是由于编译器功能。希望这会有所帮助。

答案 2 :(得分:1)

struct user {
   int id;
   char *name;
   int *friendlist;
   int *blocklist;
   char *university;
   int age;
};

定义一个包含2个int值,2个int指针和2个char指针的结构。

Userlist = malloc(sizeof(Userlist) * 10);// mind that malloc returns a void* so you should probably add a typecast 

为UserList类型的10个元素的数组分配内存;用户列表是user *类型,所以基本上你是为sizeof(指针)分配内存,在大多数系统上它是sizeof(int) - 4个字节。 您可能希望为10个user类型元素的数组分配内存:

Userlist = (user*)malloc(sizeof(user) * 10);

你仍然没有走出困境;任何类似:Userlist[0].name="Someone";的赋值仍然是未定义的行为,因为你为指针分配内存但不为它指向的缓冲区分配内存。对于这个特定的赋值,编译器为字符串分配内存,只有它在堆栈上才这样做,而不是在堆上 - 所以要小心这个!

希望这会有所帮助