【问题标题】:malloc-> how much memory is allocated? [duplicate]malloc-> 分配了多少内存? [复制]
【发布时间】:2014-02-24 15:11:45
【问题描述】:

据我所知,malloc 在内存中分配了特定数量的字节。但是我正在尝试使用它并且我分配了 4 个字节但是当我尝试在数组中存储超过 4 个(最多 200 个整数)元素时它没有给我任何错误!所以在我的代码中我不需要使用 realloc!!顺便说一句,我正在使用 Linux。最后,我很高兴听到您的任何建议......提前致谢。

tmp.h:

 #ifndef TMP_H
 #define TMP_H

 #define MAXLENGTH 4
 #define GROWFACTOR 1.5

 typedef struct stVector
 {
    int *vec;
    int length;
        int maxLength;
 }Vector; 

 Vector newEmptyVector();
 void addElement(Vector *vec, int elt);

 #endif

tmp.c:

#include "stdio.h"
    #include "stdlib.h"
    #include "tmp.h"


    Vector newEmptyVector()
    {
        Vector vec;
        vec.vec = (int*) malloc(0);
        printf("Allocating %d bytes\n", sizeof(int)*MAXLENGTH );
        vec.length = 0;
        vec.maxLength = MAXLENGTH;
        return vec;
    }


    void addElement(Vector *vec, int elt)
    {
        /*if(vec->length == vec->maxLength)
        {
            vec->vec = (int*)realloc(vec->vec,sizeof(int)* vec->maxLength * GROWFACTOR);
            vec->maxLength = vec->maxLength * GROWFACTOR;
        }*/
        vec->vec[vec->length++] = elt;
    }

main.c:

            #include"tmp.h"
    int main(int argc, char const *argv[])
    {

        Vector vector = newEmptyVector();
        printf("The length is %i and maxlength is                                    `                   `%i\n",vector.length,vector.maxLength);
        addElement(&vector,5);
        addElement(&vector,3);
        addElement(&vector,1);
        addElement(&vector,7);
        printf("The length is %i and maxlength is                                            `                       `%i\n",vector.length,vector.maxLength);
        addElement(&vector,51);
 printf("The length is %i and maxlength is %i\n",vector.length,vector.maxLength);      
        for (int i = 0; i < 200; ++i)
        {
            addElement(&vector,i);
 printf("The length is %i and maxlength is %i\n" ,vector.length, vector.maxLength);                                           
        }
        return 0;
    }

【问题讨论】:

  • 它在哪里指定当你破坏堆时它会立即崩溃?
  • 这就是我们所说的未定义行为。任何事情都有可能发生。
  • 当您执行 malloc(0) 时,您分配 个字节。你会得到either NULL 或一个有效的指针(你可以传递给free)作为回报。如果你得到一个非空指针作为回报,它指向你分配的那个零大小的内存区域,你不能使用它(因为它的大小为零)。
  • 您还应该检查mallocrealloc 的返回值以确保它们成功。这说明了您调用 realloc 的方式存在问题,因为如果它失败了,它将清除您唯一指向内存的指针。

标签: c malloc


【解决方案1】:

使用尚未分配的内存会调用未定义的行为。不要那样做。很可能,Linux 已经为您的程序提供了一页内存,而您还没有超出它。如果您触摸未分配给程序的内存,操作系统应该会导致您的程序出现段错误。但是,您所做的任何其他 mallocing 操作也可能会使用该页面的某些部分,并且您最终会损坏您的数据。

没有对溢出缓冲区进行运行时检查是 C 语言快速的部分原因,但它要求程序员不要做愚蠢的事情。

【讨论】:

    【解决方案2】:

    (仅仅因为在 C 中没有边界检查)没有引发错误这一事实并不意味着您可以安全地使用超出请求边界的内存。您很幸运没有导致分段错误,您刚刚陷入了 malloc 未声明的内存区域(假设它不是您的)。

    你可以在那里写,但不能保证你不会覆盖分配给另一个malloc的内存,或者相反,“额外”部分不会被分配给其他malloc。在您的情况下,您正在写入的内存区域似乎尚未被声明(尚未)。

    【讨论】:

    • 我使用 realloc 的方式是否正确以避免可能发生的任何内存问题??
    • @Stepfano 你能帮帮我吗
    • @OmarMuhtaseb - 你在上面使用 realloc 的方式 _ vec->vec = (int*)realloc(vec->vec,sizeof(int)* vec->maxLength * GROWFACTOR);_ 看起来正确的。 (除非你不应该转换 malloc、calloc 或 realloc 的输出)但问题在于你对 malloc 的初始调用:vec.vec = (int*) malloc(0);在那里放一个 0 以外的值,至少 sizeof(int)*numOfDesiredInts
    【解决方案3】:

    关于您的具体问题:,我分配了 4 个字节,但是当我尝试存储超过 4 个字节时,它不会给我任何错误记住,类似:

    int *anyVar = (int)malloc(0);
    anyVar[0] = 12; //Will eventually invoke undefined behavior.  
    

    写入不属于你的内存最终调用未定义的行为。坏事是你的结果看起来不错,甚至可以重复多次运行代码。但在某些时候,您的代码会失败。

    你应该这样分配:(顺便说一句)

    int numIntsInArray = 100;
    int *anyVar = malloc(sizeof(int)*numIntsInArray);//note:do not cast output of malloc
    anyVar[0] = 1;//first element of anyVar
    anyVar[99] = 1000;//last element of anyVar  
    

    不要忘记释放所有内存:

    free(anyVar);
    

    其他示例 C & C++ 中未定义的行为:

    下面的错误代码示例可以完成,您可能不会收到编译器警告,甚至可能会收到
    运行时的预期结果,但使用此代码,没有任何保证。 (例外:很好的例子)

    char * p = "string"; // Badly formed C++11, deprecated C++98/C++03
    p[0] = 'X'; // undefined behavior
    

    改为创建一个数组:

    char p[] = "string"; // Good
    p[0] = 'X';
    

    C++,你可以像这样创建/使用标准字符串:

    std::string s = "string"; // Good
    s[0] = 'X';
    

    除以零会导致未定义的行为:

    int x = 1;
    return x / 0; // undefined behavior
    

    一些指针操作可能会导致未定义的行为:

    int arr[4] = {0, 1, 2, 3};
    int* p = arr + 5;  // undefined behavior
    

    离开一个非空函数而不返回值

    int func(void)
    {
        //undefined behavior    
    }
    

    未指定或实现定义的行为:

    printf("%d %d\n", ++n, power(2, n));    //Bad
    
    i = ++i + 1; //Bad
    
    i = i + 1; // Okay
    

    【讨论】:

      猜你喜欢
      • 2011-01-03
      • 2017-01-30
      • 1970-01-01
      • 2015-08-27
      • 2012-08-28
      • 1970-01-01
      • 2012-08-28
      • 2017-05-18
      • 1970-01-01
      相关资源
      最近更新 更多