当我尝试释放使用 malloc 分配的字符指针时,为什么会出现核心转储?
Why do I get core dump when I try to free a char pointer allocated with malloc?
我正在尝试学习 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 执行 运行 可执行文件时,我确实遇到错误:*
fatal error MapViewOfFileEx shared 5'(0x66) Win 32 error 6.
也许这就是问题所在,但我认为这与此无关。
问题
sizeof(LEN+1)
将评估为整数的大小
- 分配字符串时动态分配的内存丢失
改变
bridge_text = malloc(sizeof(LEN+1));
到
bridge_text = malloc(LEN + 1);
而不是分配 bridge_text = north
,使用 strcpy
strcpy(bridge_text, north);
您不能在非动态分配的指针上调用 free()
。
当你bridge_text = north;
时,你malloc()
的东西就丢失了
做的时候
bridge_text = north;
和类似的赋值,你覆盖 malloc()
返回的实际指针。现在,使用非动态分配的指针(内存)调用 free()
是 undefined behaviour. If you want, you can refer this answer for details.
实际上,要复制内容到已经分配的内存,你可以(也应该)使用strcpy()
. Otherwise, by assigning, you're also creating memory leak,因为原始指针丢失了。
然后,
bridge_text = malloc(sizeof(LEN+1));
也是错误的。您需要将其更改为,
bridge_text = malloc(LEN+1); //sizeof(char) is 1 in c
之后,别忘了检查 malloc()
是否成功。
bridge_text
声明为 char *
。这不是其他语言所具有的字符串 class - 它只是指向某个内存的指针,该内存将作为 char
s.
的序列读取
通过为 bridge_text
分配其他值,您丢失了它的原始值(因此泄漏了您 malloc
的内存)并将其指向内存的另一部分。这就是当您尝试 free(bridge_text)
时您的程序崩溃的原因 - 指针对于释放不再有效。
此外,sizeof
运算符获取您传递给它的任何内容的字节大小 - 在本例中,大概是整数常量 - 所以您实际上只分配 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>)
。
这种行:
bridge_text = north;
不会将 north[] 中的文本字符串复制到 char 数组 bridge_text[]。
它只复制指针..
建议:
strcpy( bridge_text, north );
在当前代码中,bridge_text 中的 malloc 指针被赋值语句覆盖。
这就是 free() 导致中止的原因。
建议使用'strcpy()'将字符串复制到bridge_text点
我正在尝试学习 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 执行 运行 可执行文件时,我确实遇到错误:*
fatal error MapViewOfFileEx shared 5'(0x66) Win 32 error 6.
也许这就是问题所在,但我认为这与此无关。
问题
sizeof(LEN+1)
将评估为整数的大小- 分配字符串时动态分配的内存丢失
改变
bridge_text = malloc(sizeof(LEN+1));
到
bridge_text = malloc(LEN + 1);
而不是分配 bridge_text = north
,使用 strcpy
strcpy(bridge_text, north);
您不能在非动态分配的指针上调用 free()
。
当你bridge_text = north;
malloc()
的东西就丢失了
做的时候
bridge_text = north;
和类似的赋值,你覆盖 malloc()
返回的实际指针。现在,使用非动态分配的指针(内存)调用 free()
是 undefined behaviour. If you want, you can refer this answer for details.
实际上,要复制内容到已经分配的内存,你可以(也应该)使用strcpy()
. Otherwise, by assigning, you're also creating memory leak,因为原始指针丢失了。
然后,
bridge_text = malloc(sizeof(LEN+1));
也是错误的。您需要将其更改为,
bridge_text = malloc(LEN+1); //sizeof(char) is 1 in c
之后,别忘了检查 malloc()
是否成功。
bridge_text
声明为 char *
。这不是其他语言所具有的字符串 class - 它只是指向某个内存的指针,该内存将作为 char
s.
通过为 bridge_text
分配其他值,您丢失了它的原始值(因此泄漏了您 malloc
的内存)并将其指向内存的另一部分。这就是当您尝试 free(bridge_text)
时您的程序崩溃的原因 - 指针对于释放不再有效。
此外,sizeof
运算符获取您传递给它的任何内容的字节大小 - 在本例中,大概是整数常量 - 所以您实际上只分配 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>)
。
这种行:
bridge_text = north;
不会将 north[] 中的文本字符串复制到 char 数组 bridge_text[]。
它只复制指针..
建议:
strcpy( bridge_text, north );
在当前代码中,bridge_text 中的 malloc 指针被赋值语句覆盖。
这就是 free() 导致中止的原因。
建议使用'strcpy()'将字符串复制到bridge_text点