如果我使用大小错误的malloc会发生什么

如果我使用大小错误的malloc会发生什么

本文介绍了如果我使用大小错误的malloc会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解有关内存分配的更多信息,因此我在下面编写了一些测试代码,以查看如果我尝试分配的内存小于我所需的大小会发生什么情况.

I'm trying to learn more about memory allocation, and so I wrote some test code below to see what would happen if I tried to allocate memory of a less size than what I needed.

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

typedef struct {
    char *message;
    int number;
} Object;

int main(int argc, char *argv[]) {
    Object *obj = malloc(sizeof(Object) - 8);
    printf("The size of the struct is: %ld\n", sizeof(Object));
    printf("The size of what was allocated is: %ld\n", sizeof(*obj));

    obj->message = "Hello there! My name is Chris!";
    obj->number = 435543;

    puts(obj->message);
    printf("%d\n", obj->number);

    free(obj);

    return 0;
}

首先,在这种情况下,sizeof(* obj)是查看实际分配了多少内存的正确方法吗?其次,即使我没有分配足够的空间,为什么我仍然能够为结构对象分配值?

First of all, is sizeof(*obj) the correct way to see how much memory was actually allocated in this case? Second, why am I still able to assign values to struct objects even if I didn't allocate enough space?

我的操作系统是Ubuntu 12.10 64位,编译器是gcc 4.7.2

My OS is Ubuntu 12.10 64bit, compiler is gcc 4.7.2

以下是valgrind输出:

Here is the valgrind output:

==14257== Memcheck, a memory error detector
==14257== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==14257== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==14257== Command: ./ex
==14257==
The size of the struct is: 16
The size of what was allocated is: 16
==14257== Invalid write of size 4
==14257==    at 0x400640: main (ex.c:15)
==14257==  Address 0x51f1048 is 0 bytes after a block of size 8 alloc'd
==14257==    at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14257==    by 0x400604: main (ex.c:10)
==14257==
Hello there! My name is Chris!
==14257== Invalid read of size 4
==14257==    at 0x40065A: main (ex.c:18)
==14257==  Address 0x51f1048 is 0 bytes after a block of size 8 alloc'd
==14257==    at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14257==    by 0x400604: main (ex.c:10)
==14257==
435543
==14257==
==14257== HEAP SUMMARY:
==14257==     in use at exit: 0 bytes in 0 blocks
==14257==   total heap usage: 1 allocs, 1 frees, 8 bytes allocated
==14257==
==14257== All heap blocks were freed -- no leaks are possible
==14257==
==14257== For counts of detected and suppressed errors, rerun with: -v
==14257== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)

推荐答案

在这种特定情况下,您可能试图分配0字节,因为在大多数32位编译器中,sizeof(Object)为8. malloc(0)将返回NULL作为其要分配的无效大小,并且尝试写入地址NULL肯定会导致应用程序崩溃.

In this specific case, you are potentially trying to allocate 0 bytes, because sizeof(Object) is 8 in most 32-bit compilers. malloc(0) will return NULL as its an invalid size to be allocated, and trying to write to address NULL will certainly crash your application.

但是,假设您成功分配了4个字节,并尝试在其中写入8个字节.在单线程应用程序中,它可能应该可以正常工作,因为尽管您将写入未分配的内存空间,但它并不会完全写入虚拟内存中丢失的某些疯狂地址.

But lets suppose you successfully allocate 4 bytes, and try to write 8 bytes within it. In a single thread application it should probably work without issues, because despite you will be writing to unallocated memory space, it will not be exactly writing to some crazy address lost in the virtual memory.

但是,如果您这样做:

Object* a = (Object*)malloc(4);
Object* b = (Object*)malloc(4);

ab确实是在意甲中分配的.这意味着,在大多数32位编译器中,写入a->number会用相同的值覆盖b->message,反之亦然,因为两者都将尝试将信息存储到内存中的同一空间.

It is potentially true that a and b were allocated in serie. It means that, in most 32-bit compilers, writing to a->number will overwrite b->message with the same value and vice versa, because both will be trying to store information to the same space in memory.

这篇关于如果我使用大小错误的malloc会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 16:42