0

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

顺便说一句,我想我可以通过定义一个全局 char 数组并在子函数中分配时间信息来解决这个问题。我想了解我在 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;
}
4

7 回答 7

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

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

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

?

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

于 2012-06-19T08:40:20.767 回答
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() 看起来不错,但是当您在紧密循环中执行此操作时(例如 while(1)),它会返回从未释放的分配内存 [内存泄漏],它会非常快速地分配所有可用内存,然后繁荣

于 2012-06-19T08:41:48.987 回答
2

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

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

另外,请修正缩进。

如果你以后发现类似的问题,考虑使用类似的工具valgrind,它会对你有很大帮助(google it up!)。

于 2012-06-19T08:43:35.990 回答
1

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

于 2012-06-19T08:43:59.750 回答
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);
}

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

于 2012-06-19T09:02:31.613 回答
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' 可以在任何地方找到。

于 2012-06-19T10:40:32.690 回答
0

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

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

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

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

于 2012-06-19T08:41:34.173 回答