简体   繁体   English

C程序中的内存分配

[英]Memory allocation in a C program

I have the code block below, I deleted all unnecessary parts, just left the problematic part. 我在下面的代码块中,我删除了所有不必要的部分,只剩下有问题的部分。 My purpose to fetch the time in a specific format that I need(YYYYMMDDHHmm) by fetch_time function. 我的目的是通过fetch_time函数以我需要的特定格式(YYYYMMDDHHmm)来获取时间。 In order to return char array , I used malloc . 为了return char array ,我使用了malloc However, the program crashes if I run the code below like a minute. 但是,如果我在一分钟内运行下面的代码,程序将崩溃。 When I monitor run-time of the code by a debugging tool, the memory location that p1 points increases eg 0x72120 for the first iteration, 0x72150 for the second iteration, and so on. 当我通过调试工具监视代码的运行时时,p1指向的内存位置会增加,例如,第一次迭代为0x72120,第二次迭代为0x72150,依此类推。 So, I suspect it fails because of the memory problem. 因此,我怀疑它由于内存问题而失败。 I wonder what do I do wrong and how can I solve the problem? 我想知道我做错了什么以及如何解决该问题?

Btw, I guess I can solve the problem by defining a global char array and assining the time info in the sub-function. 顺便说一句,我想我可以通过定义一个全局char数组并在子函数中添加时间信息来解决这个问题。 I would like to learn my mistake in the malloc usage and learn the solution. 我想了解我在malloc用法中的错误并学习解决方案。 Thank you. 谢谢。

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;
}
char timedate2[13];
char *p1 = malloc(strlen(timedate2)+1);

timedate2 is uninitialised, so there's no way to guess (reliably) how much you try to allocate, and there's the possibility that the strlen call will access invalid memory and cause a segfault. timedate2尚未初始化,因此无法(可靠地)猜测您尝试分配的数量,并且strlen调用可能会访问无效的内存并导致段错误。 Did you mean to allocate 你是不是要分配

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

?

But the main problem is that fetch_time returns a newly allocated buffer each time it is called, and that is never free d. 但是主要的问题是,每次调用fetch_time时,它都会返回一个新分配的缓冲区,并且永远不会free d。

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

You allocate p1 then never use it, but overwrite it with he call to fetch_time() - this is a memory leak. 您分配p1,然后再也不使用它,但是用他对fetch_time()的调用来覆盖它-这是内存泄漏。

fetch_time() seems ok, but it returns malloced memory which is never freed [memory leak] when you do this in a tight loop (eg while(1)), it will very quickly allocate all the available memory, and then boom fetch_time()看起来还可以,但是它返回的malloc分配的内存在紧密循环(例如while(1))中执行此操作后永远不会释放[内存泄漏],它将很快分配所有可用内存,然后繁荣

The code looks correct per see. 每次看到的代码看起来都是正确的。 There's one catch thought. 有一个陷阱。 When you call malloc , you are requesting some amount of memory in which you store your date string. 调用malloc ,您请求的内存量用于存储日期字符串。 Everytime you call fetch_time you will request some (other) piece of memory with a new string. 每次调用fetch_time您都将请求带有新字符串的一些(其他)内存。 You never re-use the same piece of memory and eventually run out of memory. 您永远不会重复使用同一块内存,最终耗尽内存。 To fix that, you need to free every piece of memory you requested which will allow the system to eventually reuse it again. 要解决此问题,您需要释放所请求的每个内存,这将使系统最终再次使用它。

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

Also, please fix the indentation. 另外,请修复缩进。

If you find similar problems in the future, consider using a tool like valgrind , it will help you a lot (google it up!). 如果将来发现类似的问题,请考虑使用valgrind类的工具,它将对您有很大帮助(使用Google搜索!)。

There is a big MEMORY LEAK in your program. 您的程序中存在很大的内存泄漏。
First of all, you are allocating memory to p1 in main().You then have an infinite loop for the statement p1=fetch_time(); 首先,您要在main()中为p1分配内存。然后,对于p1=fetch_time();语句,将有一个无限循环p1=fetch_time();
In function fetch_time() , you are allocating memory to p and copying buffer. 在函数fetch_time() ,您正在将内存分配给p并复制缓冲区。 This address is returned to main(). 该地址返回到main()。 You now lose the memory address for p1 which you allocated in main. 现在,您将丢失在main中分配的p1的内存地址。
This loop runs infinite no of times thus it would reach a stage when the memory reaches its maximum limit. 此循环无限次运行,因此它将达到内存达到其最大限制的阶段。
FAULT 1 :Memory allocated to p1 not freed. FAULT 1 :分配给p1的内存未释放。
FAULT 2 : Function fetch_time keeps on allocating memory to p in each call and does not frees it. FAULT 2 :函数fetch_time会在每次调用中继续为p分配内存,但不会释放它。 FAULT 3 : Calling malloc(strlen(timedate2)+1); FAULT 3 :调用malloc(strlen(timedate2)+1); on an uninitialized string 在未初始化的字符串上

Modify your function as below 如下修改功能

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);
}

to avoid leak memory and other unexpected errors. 以避免内存泄漏和其他意外错误。

Don't You forget to free the allocated memory? 您是否忘记释放分配的内存? The code worked for 13 minutes and did not crashed. 该代码工作了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;
    }

I see one more issue in the lines below. 我在以下几行中看到另一个问题。

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

'strlen' function searches for the first symbol '\\0' in the given array of chars. 'strlen'函数在给定的字符数组中搜索第一个符号'\\ 0'。 But in this case the content of the array 'timedate2' is undefined and the symbol '\\0' may be found anywhere. 但是在这种情况下,数组'timedate2'的内容未定义,并且符号'\\ 0'随处可见。

why are you reassigning p1(already pointing to allocated memory). 为什么要重新分配p1(已经指向分配的内存)。

Also, calling fetch_time() indefinitely will cause heap overflow. 另外,无限期地调用fetch_time()会导致堆溢出。

What you can do is pass the p1(pointer) as argument to the fetch_time() and copy the timeinfo into the already allocated memory. 您可以做的是将p1(pointer)作为参数传递给fetch_time()并将timeinfo复制到已分配的内存中。

At last, remember to free the memory allocated by your program. 最后,请记住free程序分配的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM