C程序中的内存分配

时间:2012-06-19 08:35:32

标签: c memory-management malloc

我有下面的代码块,我删除了所有不必要的部分,只是留下了有问题的部分。我的目的是通过fetch_time函数以我需要的特定格式(YYYYMMDDHHmm)获取时间。为了return char array,我使用了malloc。但是,如果我像下面那样运行下面的代码,程序就会崩溃。当我通过调试工具监视代码的运行时间时,p1指向的存储器位置增加,例如第一次迭代时为0x72120,第二次迭代时为0x72150,依此类推。因此,我怀疑它因内存问题而失败。我想知道我做错了什么,我该如何解决这个问题呢?

顺便说一句,我想我可以通过定义一个全局字符数组并在子函数中确定时间信息来解决问题。我想了解malloc使用中的错误并学习解决方案。谢谢。

int main(int argc,char *argv[]){
    char timedate2[13];
    char *p1 = malloc(strlen(timedate2)+1);
    if(!p1){exit(1);}

    while(1){
        p1=fetch_time();
    }
}

char *fetch_time() {
    char *p;
    time_t rawtime;
    struct tm * timeinfo;
    char buffer [13];

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
    strftime (buffer,13,"%04Y%02m%02d%02k%02M",timeinfo);
    p = (char *)malloc(sizeof(buffer));
    strcpy(p, buffer);
    return p;
}

7 个答案:

答案 0 :(得分:2)

char timedate2[13];
char *p1 = malloc(strlen(timedate2)+1);

timedate2未初始化,因此无法猜测(可靠地)您尝试分配多少,并且strlen调用可能会访问无效内存并导致段错误。你的意思是分配

char *p1 = malloc(sizeof timedate2 + 1);

但主要问题是fetch_time每次调用时都会返回一个新分配的缓冲区,而且永远不会free d。

答案 1 :(得分:2)

char timedate2[13];
/* timedate2 is not initialized, so strlen is unpredictable at best*/
char *p1 = malloc(strlen(timedate2)+1);

你分配p1然后从不使用它,但是在调用fetch_time()时覆盖它 - 这是内存泄漏。

fetch_time()似乎没问题,但是它会返回malloced内存,当你在紧密循环中执行此操作时永远不会释放[内存泄漏](例如while(1)),它将非常快速地分配所有可用内存,然后的动臂

答案 2 :(得分:2)

代码看起来是正确的。有一个想法。当您致电malloc时,您正在请求存储日期字符串的大量内存。每当你调用fetch_time时,你都会用一个新字符串请求一些(其他)内存。你永远不会重复使用同一块内存,最终耗尽内存。要解决这个问题,你需要释放你请求的每一块内存,这样系统最终可以重新使用它。

while(1) {
    p1=fetch_time();
    // do something with p1
    free(p1);
}

另外,请修复缩进。

如果您在将来发现类似的问题,请考虑使用valgrind之类的工具,它会对您有所帮助(google it up!)。

答案 3 :(得分:1)

您的计划中存在大量内存泄漏 首先,你是在main()中为p1分配内存。然后你有一个无限循环的语句p1=fetch_time();
在函数fetch_time()中,您正在为p和复制缓冲区分配内存。该地址返回给main()。您现在丢失了在main中分配的p1的内存地址。
此循环无限次运行,因此当内存达到其最大限制时,它将达到一个阶段。
FAULT 1:分配给p1的内存未释放。
FAULT 2:函数fetch_time继续在每次调用中将内存分配给p并且不释放它。 FAULT 3:在未初始化的字符串上调用malloc(strlen(timedate2)+1);

答案 4 :(得分:1)

修改您的功能如下

while(1){
   fetch_time(p1, strlen(timedate2) + 1);
  }
}
void fetch_time(char * time_str, int format_len)
    time_t rawtime;
    struct tm * timeinfo;
    char buffer [13];

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
    strftime (buffer,13,"%04Y%02m%02d%02k%02M",timeinfo);
    strncpy(p, buffer, format_len);
}

避免泄漏内存和其他意外错误。

答案 5 :(得分:1)

你不忘记释放分配的内存吗?该代码工作了13分钟,并没有崩溃。

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

char* fetch_time();

    int main(int argc,char *argv[]){

        char timedate2[13];
        char *p1 = malloc(strlen(timedate2)+1);
        if(!p1){exit(1);}
        free(p1);

        while(1){
               p1=fetch_time();
               free(p1);
        }
    }

    char* fetch_time() {
        char *p;
        time_t rawtime;
        struct tm * timeinfo;
        char buffer [13];

        time ( &rawtime );
        timeinfo = localtime ( &rawtime );
        strftime (buffer,13,"%04Y%02m%02d%02k%02M",timeinfo);
        p = (char *)malloc(sizeof(buffer));
        strcpy(p, buffer);

        return p;
    }

我在下面的行中再看到一个问题。

char timedate2[13];
char *p1 = malloc(strlen(timedate2)+1);

'strlen'函数在给定的字符数组中搜索第一个符号'\ 0'。但在这种情况下,数组'timedate2'的内容是未定义的,符号'\ 0'可以在任何地方找到。

答案 6 :(得分:0)

为什么要重新分配p1(已指向已分配的内存)。

此外,无限期地调用fetch_time()将导致堆溢出。

你可以做的是将p1(指针)作为参数传递给fetch_time(),并将timeinfo复制到已经分配的内存中。

最后,请记住free程序分配的内存。