字符指针和 malloc
Char Pointers and malloc
我对字符指针的概念有点困惑,所以我编写了一个简单的代码,只打印用户(我)提供的我的名字。我也想练习malloc所以引用了RAM中某块内存的指针,但是我实在不知道在"sizeof(char) *"后面放什么,因为那是用户输入,还没有定下来。
此外,这样做之后,我释放了内存,但我在命令行上收到一条错误消息:
*** Error in `./char': double free or corruption (fasttop): 0x00000000017fe030 ***
Aborted
好像我释放了同一个内存两次之类的,但我不知道该删除或添加什么。请帮忙!
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}
您没有包含 get_string()
的代码,但您用 return 的值覆盖了 strings
,这是错误的。您传递给 free()
的地址必须来自 malloc()
,而且您似乎违反了这一点(除了丢失原始 returned 地址的 10 个字节)。
假设 get_string()
returns 静态存储(即您不需要释放它)您可以在不涉及 malloc()
.
的情况下执行此操作
如果您确实想要,这样的方法可能会起作用:
printf("What is your name?\n");
const char *name = get_string();
const size_t nlen = strlen(name);
char * const name_copy = malloc(nlen + 1);
if(name_copy != NULL)
{
memcpy(name_copy, name, nlen + 1);
printf("Hello %s (from my own memory!)\n", name_copy);
free(name_copy);
}
这很复杂,但你明白了。
问题是您的 get_strings
覆盖了您的初始 malloc
。指针值是一个值。通过将它等同于其他东西,您 替换了 您的 malloc
值。
首先你已经创建了一个动态内存,它将被*strings指向。但是随后您使用 *strings 指针指向本地字符串(来自 get_string() 函数)。当您调用 free 时,程序正在尝试删除本地(堆栈)引用并抛出错误。
要解决该错误,程序应该是
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strcpy(strings, get_string()); // Use strcpy instead of assigning
printf("Hello %s\n", strings);
free (strings);
return 0;
}
strings = get_string();
行实际上将get_string()
返回的值赋给了strings
。它不会将其写入您分配的内存中。
因此 malloc()
返回的值已被覆盖(在本例中丢失)。
free(strings)
正在释放 get_string()
返回的任何内容。这个问题没有提供代码,但大概对 free()
它无效。
因为 运行-time 告诉你它被释放了两次我猜你已经在 get_string()
中分配了内存然后释放了它并返回了一个无效的指针。
如果您想使用分配的内存,您需要更改 get_string()
以接受指针:
void get_string(char *str){
//Do whatever writing you value into str[] as an array of char..
}
好的做法是:
void get_string(char *str, size_t max){
//Do whatever writing you value into str[] as an array of char..
//Use max to avoid writing beyond the end of the space allocated...
}
然后调用get_string(strings,10);
。
编辑: 经过一些研究,发现了缺陷。 get_string()
不直接 free()
字符串 returns 而是将其添加到库进行的分配列表中,这些分配在退出时被释放(在一个名为 teardown()
的函数中 registered具有 atexit()
或其他依赖于编译器的功能)。
这是糟糕的设计,因为没有提供消费者代码自身释放内存的安全方法,而在典型的用例中,整个应用程序执行不需要内存。 get_double()
更糟,因为它从不 returns 分配的数据,但从不重用它,相当于直接内存泄漏。
代码应该是:
- 遵守文档并要求消费者代码
free()
字符串(为清楚起见,可以将其重命名为 get_string_alloc()
)。
- 提供一个库例程来释放字符串(
get_new_string()
和 release_string()
)
在 C 中没有很好的方法来转移已分配内存的所有权,但在剩余的执行过程中一直保留它绝对不是答案。
许多图书馆四处走动,将分配推到消费者代码上,但是当无法知道所需的 space 的完整大小时,这是很繁重的,例如这里。
我建议将 _alloc()
放在 returns 消费者代码稍后必须 free()
.
对象的任何函数的末尾
所以所提问题的答案是删除 malloc()
和 free()
,因为库同时处理这两个问题。但是请注意,如果您的程序多次调用该函数和其他内部依赖它的函数(如 get_double()
),您可能 运行 内存不足,因为库已死 space。
在语句处分配内存:
strings = get_string();
您不必 malloc
它( char *strings = malloc(sizeof(char) * 10);
)
没有 malloc
它会正常工作
char *strings;
- 不需要新的 malloc,因为从 get_string() 函数返回的字符串已经在堆上,您只需要获取指向第一个字符的指针。 (get_string() function reference)
字符串=get_string();
printf("Hello %s\n", 字符串);
- 打印字符串后,您应该释放为其分配的内存,如 get_string() 函数参考中所述
Stores string on heap (via malloc); memory must be freed by caller to
avoid leak.
我认为其他一切都很好,试试这个代码:
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings;
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}
我对字符指针的概念有点困惑,所以我编写了一个简单的代码,只打印用户(我)提供的我的名字。我也想练习malloc所以引用了RAM中某块内存的指针,但是我实在不知道在"sizeof(char) *"后面放什么,因为那是用户输入,还没有定下来。 此外,这样做之后,我释放了内存,但我在命令行上收到一条错误消息:
*** Error in `./char': double free or corruption (fasttop): 0x00000000017fe030 ***
Aborted
好像我释放了同一个内存两次之类的,但我不知道该删除或添加什么。请帮忙!
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}
您没有包含 get_string()
的代码,但您用 return 的值覆盖了 strings
,这是错误的。您传递给 free()
的地址必须来自 malloc()
,而且您似乎违反了这一点(除了丢失原始 returned 地址的 10 个字节)。
假设 get_string()
returns 静态存储(即您不需要释放它)您可以在不涉及 malloc()
.
如果您确实想要,这样的方法可能会起作用:
printf("What is your name?\n");
const char *name = get_string();
const size_t nlen = strlen(name);
char * const name_copy = malloc(nlen + 1);
if(name_copy != NULL)
{
memcpy(name_copy, name, nlen + 1);
printf("Hello %s (from my own memory!)\n", name_copy);
free(name_copy);
}
这很复杂,但你明白了。
问题是您的 get_strings
覆盖了您的初始 malloc
。指针值是一个值。通过将它等同于其他东西,您 替换了 您的 malloc
值。
首先你已经创建了一个动态内存,它将被*strings指向。但是随后您使用 *strings 指针指向本地字符串(来自 get_string() 函数)。当您调用 free 时,程序正在尝试删除本地(堆栈)引用并抛出错误。
要解决该错误,程序应该是
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strcpy(strings, get_string()); // Use strcpy instead of assigning
printf("Hello %s\n", strings);
free (strings);
return 0;
}
strings = get_string();
行实际上将get_string()
返回的值赋给了strings
。它不会将其写入您分配的内存中。
因此 malloc()
返回的值已被覆盖(在本例中丢失)。
free(strings)
正在释放 get_string()
返回的任何内容。这个问题没有提供代码,但大概对 free()
它无效。
因为 运行-time 告诉你它被释放了两次我猜你已经在 get_string()
中分配了内存然后释放了它并返回了一个无效的指针。
如果您想使用分配的内存,您需要更改 get_string()
以接受指针:
void get_string(char *str){
//Do whatever writing you value into str[] as an array of char..
}
好的做法是:
void get_string(char *str, size_t max){
//Do whatever writing you value into str[] as an array of char..
//Use max to avoid writing beyond the end of the space allocated...
}
然后调用get_string(strings,10);
。
编辑: 经过一些研究,发现了缺陷。 get_string()
不直接 free()
字符串 returns 而是将其添加到库进行的分配列表中,这些分配在退出时被释放(在一个名为 teardown()
的函数中 registered具有 atexit()
或其他依赖于编译器的功能)。
这是糟糕的设计,因为没有提供消费者代码自身释放内存的安全方法,而在典型的用例中,整个应用程序执行不需要内存。 get_double()
更糟,因为它从不 returns 分配的数据,但从不重用它,相当于直接内存泄漏。
代码应该是:
- 遵守文档并要求消费者代码
free()
字符串(为清楚起见,可以将其重命名为get_string_alloc()
)。 - 提供一个库例程来释放字符串(
get_new_string()
和release_string()
)
在 C 中没有很好的方法来转移已分配内存的所有权,但在剩余的执行过程中一直保留它绝对不是答案。 许多图书馆四处走动,将分配推到消费者代码上,但是当无法知道所需的 space 的完整大小时,这是很繁重的,例如这里。
我建议将 _alloc()
放在 returns 消费者代码稍后必须 free()
.
所以所提问题的答案是删除 malloc()
和 free()
,因为库同时处理这两个问题。但是请注意,如果您的程序多次调用该函数和其他内部依赖它的函数(如 get_double()
),您可能 运行 内存不足,因为库已死 space。
在语句处分配内存:
strings = get_string();
您不必 malloc
它( char *strings = malloc(sizeof(char) * 10);
)
没有 malloc
它会正常工作
char *strings;
- 不需要新的 malloc,因为从 get_string() 函数返回的字符串已经在堆上,您只需要获取指向第一个字符的指针。 (get_string() function reference)
字符串=get_string();
printf("Hello %s\n", 字符串);
- 打印字符串后,您应该释放为其分配的内存,如 get_string() 函数参考中所述
Stores string on heap (via malloc); memory must be freed by caller to avoid leak.
我认为其他一切都很好,试试这个代码:
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings;
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}