请问这会泄漏内存吗? [英] will this leak memory?
问题描述
你好,
我是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));
会为您提供计数字节的缓冲区,因此您可以从buffer
到buffer + 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 dotempalloc = (char*) realloc(buffer,count*sizeof(x));
that gives you a buffer of count bytes, so you can write to it frombuffer
tobuffer + count - 1
, while*(buffer+count) = x;
writes over the boundary.
Second, when you callprintf("%s",buffer);
you assume that buffer is a null terminated sequence of character, this is not the case in your code, soprintf
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"之后移位了一个,因此给出了
Yourgetcommand
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屋!