我试图了解C中的基础知识,但我无法让malloc()
和free()
工作。
这是我的代码,它会根据输入在屏幕中央打印一个单词。 (删除了一些声明并包括缩短声明)
char *bridge_text;
char menu1[] = "Key input: \n\t n. car arrive north \
\n\t s. car arrive south \
\n\t r. empty bridge \
\n\t q. quit";
int main()
{
bridge_text = malloc(sizeof(char)*(LEN+1)); //misprinted here before
initscr();
getmaxyx(stdscr,row, col);
mvprintw(2, 4, menu1);
refresh();
while(run)
{
switch(getchar())
{
case 'q':
run = 0;
break;
case 'n':
/*not shown: char north[] = "NORTH";*/
bridge_text = north;
break;
case 's':
bridge_text = south;
break;
case 'r':
bridge_text = empty;
break;
default:
bridge_text = empty;
break;
}
mvprintw(row/2, (col-5)/2, bridge_text);
refresh();
}
endwin();
/* adding free() here results in core dump. */
free(bridge_text);
return 0;}
我将gcc与cygwin一起使用,程序运行正常,我可以使用' q' -key退出程序,但是......
'n'
,'e'
或'r'
(指定bridge_text
一个字符串),
然后尝试退出,它会导致核心转储。如果我,这工作正常
删除free()
使用cygwin:*
运行可执行文件时出错致命错误MapViewOfFileEx共享5'(0x66)赢32错误6。
也许这就是问题,但我认为它与此无关。
答案 0 :(得分:4)
问题
sizeof(LEN+1)
将评估为整数更改
bridge_text = malloc(sizeof(LEN+1));
到
bridge_text = malloc(LEN + 1);
而不是分配bridge_text = north
,请使用strcpy
strcpy(bridge_text, north);
答案 1 :(得分:3)
在你的评论中,你有:
bridge_text = north;
然后你做:
north
表示您将bridge_text
的地址存储在free(bridge_text)
中。然后你尝试north
- 这意味着你试图释放free
- 但你不能这样做,你只能使用malloc
分配north
个数据,这个情况不是malloc
。
当您bridge_text = north;
某事并将其结果分配给指针,然后为该指针指定其他内容时(就像您现在使用malloc(sizeof(LEN+1))
所做的那样),通常会丢失指向最初分配的数据的指针和泄漏的记忆。所以你不应该这样做。
备注不使用malloc(LEN + 1)
,而使用zii.widgets.grid.CGridView
也是正确的。
答案 2 :(得分:2)
在做的时候
bridge_text = north;
和simmilar 分配,您覆盖 malloc()
返回的实际指针。现在,使用非动态分配的指针(内存)调用free()
为undefined behaviour。如果您愿意,可以refer this answer for details。
实际上,要将复制内容复制到已分配的内存,您可以(并且应该)使用strcpy()
。否则,通过分配,您还会创建memory leak,因为原始指针会丢失。
然后,
bridge_text = malloc(sizeof(LEN+1));
也错了。您需要将其更改为,
bridge_text = malloc(LEN+1); //sizeof(char) is 1 in c
在此之后,不要忘记检查malloc()
是否成功。
答案 3 :(得分:0)
您无法在非动态分配的指针上调用free()
。
执行malloc()
bridge_text = north;
' d丢失了什么
答案 4 :(得分:0)
bridge_text
被声明为char *
。这不是其他语言所具有的字符串类 - 它只是指向某些内存的指针,该内存将被视为char
s的序列。
通过将其他值分配给bridge_text
,您已丢失其原始值(因此泄露了malloc
&d; d)的内存,并将其指向内存的另一部分。这就是当您尝试free(bridge_text)
时程序崩溃的原因 - 指针不再有效用于释放。
另外,另外,sizeof
运算符获取传递它的任何字节大小 - 在本例中为a,可能是整数常量 - 因此实际上只分配5或9个字节(取决于系统) ),而不是(LEN + 1)
。
您可以通过多种方式修复代码:
char
缓冲区。将声明更改为char bridge_text[LEN + 1]
并删除malloc
和free
来电。然后使用strcpy
用数据填充它。只需使用bridge_text作为指向包含您要打印的项目的其他缓冲区的指针。如果一切都是恒定的,或者你将任何动态放在一个单独的缓冲区中(不要忘记确保你的动态缓冲区不会超出范围),这就行了,例如。
char dynamic_string [50];
int value = 10;
sprintf(dynamic_string,"Value = %d", value);
bridge_text = dynamic_string;
继续使用它,但要解决malloc
尺寸问题,并将bridge_text = <something>
更改为strcpy(bridge_text,<something>)
。
答案 5 :(得分:0)
这种路线:
bridge_text = north;
不会将north []中的文本字符串复制到char数组bridge_text []。
它只复制指针..
建议:strcpy( bridge_text, north );
在当前代码中,bridge_text中的malloc指针被赋值语句覆盖。
这就是free()导致中止的原因。
建议使用&#39; strcpy()&#39;将字符串复制到bridge_text指向的位置