请问这会泄漏内存吗? [英] will this leak memory?

查看:75
本文介绍了请问这会泄漏内存吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,
我是C语言的新手,我想知道以下代码是否会泄漏内存?如果是这样,我需要释放什么,这样它才不会泄漏.谢谢!

Hello,
I''m new to C and I was wondering if the following code would leak memory? If so, what do I need to free so it won''t leak. Thanks!

#include <stdio.h>
#include <stdlib.h>
char *getcommand(void);
int main(){
    char *cmd;
        while(1){
        cmd = getcommand();
        if (cmd[0] == ''q''){
            printf("exit character has been detected\n");
            return(0);
        }
        printf("the command is %s\n",cmd);
        }
    return 0;
}
char *getcommand(void){
    char x;
    char *buffer=NULL;
    char *tempalloc;
    int count = 0;
    do{
        count++;
        x = getchar();
        tempalloc = (char*) realloc(buffer,count*sizeof(x));
        if(tempalloc == NULL){
            puts("memory could not be allocated!");
            free(buffer);
            exit(1);
        }
        else{
        buffer = tempalloc;
        *(buffer+count) = x;
        printf("%s",buffer);
        }
    }while(x != ''\n'');
    *(buffer++) = ''\0'';
    return buffer;
}

推荐答案

快速浏览一下您的代码,我发现了两个问题(可能更多;)):

首先是内存溢出,执行tempalloc = (char*) realloc(buffer,count*sizeof(x));会为您提供计数字节的缓冲区,因此您可以从bufferbuffer + count - 1对其进行写操作,而*(buffer+count) = x;则在边界上进行写操作.

其次,当您调用printf("%s",buffer);时,假定缓冲区是一个以空字符终止的字符序列,但在您的代码中情况并非如此,因此printf会打印所有字符,直到找到"0"为止,确定您会以前有很多花哨的性格!并且您可以访问堆栈中某个位置的字符(或不访问).

我假设您是学生,我鼓励您在调试器中逐步运行代码,在键盘附近用笔和纸查看缓冲区和tempalloc变量...

好的"C"练习,您将喜欢C ++和STL容器!
Having a quick look at your code, I see two problems (may be more ;)) :

First is memory overrun, you do tempalloc = (char*) realloc(buffer,count*sizeof(x)); that gives you a buffer of count bytes, so you can write to it from buffer to buffer + count - 1, while *(buffer+count) = x; writes over the boundary.

Second, when you call printf("%s",buffer); you assume that buffer is a null terminated sequence of character, this is not the case in your code, so printf prints all the character until it found a ''0'', sure you will have a lot of fancy character before ! And you access characters somewhere in the stack (or not).

I assume you are a student, I encourage you to run your code step by step in a debugger, looking buffer and tempalloc variables, with a pen and piece of paper near the keyboard...

Good "C" exercise, you will enjoy C++ and STL container !


您的getcommand 与缓冲区有点混乱.
在do语句中循环时,将使缓冲区指向一个缓冲区,该缓冲区在读取字符时会扩大.

退出循环后,*(buffer ++)=''\ 0''语句实际上将缓冲区指针放在"\ 0"之后移位了一个,因此给出了
Your getcommand does a a little mess with the buffers.
While looping in the do statement, buffer is made pointing to a buffer that is enlarged as characters are read.

After exiting the loop, the *(buffer++)=''\0'' statement in fact shift the buffer pointer by one after placing a ''\0'' thus giving
|0|_|_|_|_|_|_|_|_|_|_|
   ^buffer


正确的语句应该是buffer[count]=''\0'',给出


The proper statement should have probably been buffer[count]=''\0'', giving

|_|_|_|_|_|_|_|_|_|0|
 ^buffer


但是请注意,对realloc 的调用应分配(count+1)*sizeof(x),否则您将没有空间在末尾存储"\ 0"字符.

此时,通过返回buffer,您可以使调用者有责任释放已分配的内容.
在回到新的getcommand之前和从main返回之前,必须先调用free(cmd).


But beware that your call to realloc should allocate (count+1)*sizeof(x), otherwise you will have no space to store the ''\0'' character at end.

At this point, by returning buffer, you give the caller the responsibility to free what have been allocated.
You have to call free(cmd) before loping back to a new getcommand, and before returning from main.

int main(){
    char *cmd;
        while(1)
        {
            cmd = getcommand();
            if (cmd[0] == 'q')
            {
                printf("exit character has been detected\n");
                break;
            }
            printf("the command is %s\n",cmd);
            free(cmd);
        }
    free(cmd);
    return 0;
}


当您刚接触C时,我强烈建议您不要弄乱内存分配和指针,它只会以眼泪结束.正如您似乎想从stdin中读取一行并将其返回给调用方一样,为什么不只使用设计用于执行此类操作的功能之一,例如fgets()吗?

不用担心效率",这种程序的I/O开销将远远大于您通过使用malloc/realloc和free所获得的任何收益.

最后一件事-如果您想从函数中返回缓冲区但又不想弄乱手动复制数组,请考虑使用一种结构来保存数据:

struct cmd
{
字符文本[80];
};

当您返回其中之一时,编译器将生成代码以复制命令文本,并且它将分配和释放所使用的内存.

干杯,

As you''re new to C I''d strongly advise against messing about with memory allocation and pointers, it will only end in tears. As you seem to want to read a line from stdin and return it to the caller why not just use one of the functions designed to do this sort of thing, e.g. fgets() ?

Don''t worry about "efficiency," the I/O overhead with this sort of program is going to be far greater than any gain you''ll get from mucking about with malloc/realloc and free.

One final thing - if you want to return the buffer from the function but don''t want to have to mess manually copying arrays, consider using a structure to hold the data:

struct cmd
{
char text[ 80 ];
};

When you return one of these the compiler will generate the code to copy the command text AND it will allocate and release the memory used.

Cheers,

Ash


这篇关于请问这会泄漏内存吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆